Using C# to Generate Random String with Character Filter

I haven’t posted anything for awhile, and today while toying around with a few different things I decided to tweak my random string generator.  So I thought I’d share.

So here we have two methods; one for Unicode and one for ASCII. My thought was that when generating a simple password for US English keyboards, I’d just use a simple ASCII generator using characters available on the keyboard. For for the rest of you folks who don’t have a US English keyboard, maybe there are some options to generate a random string with a custom range filter. 

public static string GetRandomUnicodeString(int length, int maxValue, Predicate<int> valueFilter)  
{
    byte[] seedBuff = new byte[4];
    byte[] charBuff;

    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(seedBuff); // The array is now filled with cryptographically strong random bytes.

    using (MemoryStream ms = new MemoryStream())
    {
        using (StreamWriter sw = new StreamWriter(ms, new UTF8Encoding(false, false)))
        {
            var random = new Random(BitConverter.ToInt32(seedBuff, 0));

            for (int i = 0; i < length; i++)
            {
                int temp = random.Next(maxValue); //should we cap? 

                while (!valueFilter(temp))
                    temp = random.Next(maxValue);

                sw.Write((char)temp);
            }
        }
        charBuff = ms.ToArray();
    }
    return new System.Text.UTF8Encoding(false, false).GetString(charBuff);
}

public static string GetRandomASCIIString(int length)  
{
    return GetRandomUnicodeString(length, 0x7E, o => o >= 0x21 && o <= 0x7E);
    //return GetRandomUnicodeString(length, 126, o => o >= 33 && o <= 126); //could use integers instead
}

So when using the Unicode method, you have to specify a max value; otherwise, the random generator will choke if you want a small range of numbers when randomizing a pool of 65,535 values. So the cap will help performance. The filter expression should filter out the random results so you only get the characters you want.

The ASCII method is a pretty simple example of how this works.  I want a max value of 126, and I want characters in the range of 33 through 126. I used hex (because the Windows character map uses hex).

Hope you all find it useful.  Let me know how it goes.