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 *


Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: `POST https://dc.services.visualstudio.com/v2/track` resulted in a `400 Invalid instrumentation key` response: {"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":400,"message":"Invalid instrumentation key"}]} in D:\home\site\wwwroot\wp-content\plugins\application-insights\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php:113 Stack trace: #0 D:\home\site\wwwroot\wp-content\plugins\application-insights\vendor\guzzlehttp\guzzle\src\Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response)) #1 D:\home\site\wwwroot\wp-content\plugins\application-insights\vendor\guzzlehttp\promises\src\Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response)) #2 D:\home\site\wwwroot\wp-content\plugins\application-insights\vendor\guzzlehttp\promises\src\Promise.php(156): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\P in D:\home\site\wwwroot\wp-content\plugins\application-insights\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php on line 113