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.
0 Comments