Home > C# > A Simplistic Random String Generation Snippet

A Simplistic Random String Generation Snippet

January 25th, 2010

This is just a little snippet that generates a random string, containing both upper and lower case characters and special chars, so there’s a range of 93 possible characters, taken from the UTF-8 character table. I thought I’d post it as the snippets I’ve seen after a quick search usually just generate strings with characters ranging from ‘A’ to ‘Z’, or do not work with properly initialized seeds.

Note that this method uses a static int field (seedCounter) when in comes to creating a random seed. This counter is incremented in a thread safe manner every time the method is being invoked. This simple trick is a simple workaround to the notoriously unreliable Random class, and effectively prevents double seeds (and thus: duplicate “random strings”) if the GetRandomString method is being invoked several times immediately. As an alternative, you could also use a static Random field, which would only have to be initialized once. My implementation has the smaller footprint (and integer variable), while a Random field would perform much better (currently, every invocation calculates a seed and creates a new Random instance). The better choice depends on the context I guess:

 

/// <summary>
/// A counter that is being incremented with every invocation of
/// <see cref="GetRandomString"/>.
/// </summary>
private static int seedCounter = (int)DateTime.Now.Ticks;


/// <summary>
/// Generates a random string of a given length, which consists
/// of characters taken from the UTF-8 table (0x21 - 0x7e).
/// </summary>
/// <param name="length">The length of the random string.</param>
/// <returns>Random characters.</returns>
public static string GetRandomString(int length)
{
  const int lower = 0x21;
  const int upper = 0x7e;

  StringBuilder builder = new StringBuilder();

  //increment thread-safe
  seedCounter = Interlocked.Increment(ref seedCounter);

  //create random with the seed (make sure it's not int.MinValue)
  Random rnd = new Random(seedCounter %int.MinValue);

  for (int i = 0; i < length; i++)
  {
    builder.Append((char) rnd.Next(lower, upper));
  }

  return builder.ToString();
}

 

Accordingly, invoking the method like this:

string random = GetRandomString(10);

 

…generates you a string comparable to this one: 2#,R`6>Cz{


Author: Categories: C# Tags:
  1. January 25th, 2010 at 19:21 | #1

    If you want a cryptographically secure random string, you should use the System.Security.Cryptography.RandomNumberGenerator class instead of the System.Random class:

    public static string GetRandomString(int length)
    {
    if (0 >= length) throw new ArgumentOutOfRangeException();

    const byte lower = 0×21;
    const byte upper = 0x7e;

    int resultIndex = 0;
    char[] result = new char[length];
    byte[] buffer = new byte[length];
    var rnd = RandomNumberGenerator.Create();

    while (resultIndex lower <= b && b (char)b).ToArray();
    if (0 != temp.Length)
    {
    int l = Math.Min(temp.Length, length – resultIndex);
    Array.Copy(temp, 0, result, resultIndex, l);
    resultIndex += l;
    }
    }

    return new String(result);
    }

  2. January 25th, 2010 at 19:22 | #2

    OK, the comments don’t like less-than characters!

    public static string GetRandomString(int length)
    {
    if (0 >= length) throw new ArgumentOutOfRangeException();

    const byte lower = 0×21;
    const byte upper = 0x7e;

    int resultIndex = 0;
    char[] result = new char[length];
    byte[] buffer = new byte[length];
    var rnd = RandomNumberGenerator.Create();

    while (resultIndex < length)
    {
    rnd.GetNonZeroBytes(buffer);
    char[] temp = buffer.Where(b => lower &lt= b && b <= upper).Select(b => (char)b).ToArray();
    if (0 != temp.Length)
    {
    int l = Math.Min(temp.Length, length – resultIndex);
    Array.Copy(temp, 0, result, resultIndex, l);
    resultIndex += l;
    }
    }

    return new String(result);
    }

  1. No trackbacks yet.