Cryptographically Secure Random String

I’ve been trying to generate unique referal codes composed of uppercase letters for a project and although it’s not really necessary I wanted to make these as cryptographically sound as possible so I could reuse the code later in a personal password generator project.

Turns out it wasn’t as simple as I’d hoped but the below is what I came up with wich is mostly borrowed from the answer by xantos in this Stack Overflow article.


public static string GetUniqueToken(int length, string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_")
{
	using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
	{
		byte[] data = new byte[length];

		// If chars.Length isn't a power of 2 then there is a bias if we simply use the modulus operator. The first characters of chars will be more probable than the last ones.
		// buffer used if we encounter an unusable random byte. We will regenerate it in this buffer
		byte[] buffer = null;

		// Maximum random number that can be used without introducing a bias
		int maxRandom = byte.MaxValue - ((byte.MaxValue + 1) % chars.Length);

		crypto.GetBytes(data);

		char[] result = new char[length];

		for (int i = 0; i < length; i++)
		{
			byte value = data[i];

			while (value > maxRandom)
			{
				if (buffer == null)
				{
					buffer = new byte[1];
				}

				crypto.GetBytes(buffer);
				value = buffer[0];
			}

			result[i] = chars[value % chars.Length];
		}

		return new string(result);
	}
}

This just generates a random string of a given length but I’ll update it at some later point to work with password strength rules for my password generator project.


Leave a Reply

Your email address will not be published. Required fields are marked *