Jack
Jack

Reputation: 7557

9 character unique random string (for single table)

I want to generate a 9 digit unique random string. Currently I am using

Guid.NewGuid().ToString().Replace("-","").Substring(0,9)

But I am afraid it would have a collision very soon. Is there any better way for this or would this be OK?

Upvotes: 1

Views: 1848

Answers (3)

Jack
Jack

Reputation: 7557

I've decided to answer my own question since this is the simplest answer that I found. Credits to Random String Generator Returning Same String

    private static Random random = new Random((int)DateTime.Now.Ticks);
    private static object locker = new object();

    private static string RandomString(int size)
    {
        StringBuilder builder = new StringBuilder();
        char ch;
        for (int i = 0; i < size; i++)
        {
            lock (locker)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
            }
            builder.Append(ch);
        }

        return builder.ToString();
    }

Upvotes: 0

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

If you take a sub string of a GUID you are not guaranteed randomness uniqueness at all.

See my answer to a older SO question to fulfill your randomness requirement. Here is the basic code to do it.

public static string CreateRandomString(int length)
{
    length -= 12; //12 digits are the counter
    if (length <= 0)
        throw new ArgumentOutOfRangeException("length");
    long count = System.Threading.Interlocked.Increment(ref counter);
    Byte[] randomBytes = new Byte[length * 3 / 4];
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(randomBytes);

    byte[] buf = new byte[8];
    buf[0] = (byte)count;
    buf[1] = (byte)(count >> 8);
    buf[2] = (byte)(count >> 16);
    buf[3] = (byte)(count >> 24);
    buf[4] = (byte)(count >> 32);
    buf[5] = (byte)(count >> 40);
    buf[6] = (byte)(count >> 48);
    buf[7] = (byte)(count >> 56);
    return Convert.ToBase64String(buf) + Convert.ToBase64String(randomBytes);
}

it gives you 12 digits of counting to prevent collisions and any additional digits you want of randomness. you can modify the code as you want to make shorter than 12 digit strings.

Upvotes: 4

Davio
Davio

Reputation: 4737

Well, with GUID, it is guaranteed to be globally unique, but only as a whole. You can't assume randomness about a substring of the entire GUID.

Moreover, if you are generating from the same source, there WILL be collisions in substrings because the algorithm uses some of the same variables, for instance the computer's MAC address although I'm not entirely sure about that one. It suffices as an example though.

So if you want to create random strings from substrings of GUIDs, you have to keep track of all the previous GUIDs to make sure there are no collisions. You would get a Las Vegas algorithm.

Upvotes: 1

Related Questions