Skip to content

Instantly share code, notes, and snippets.

@rossmurray
Last active December 17, 2015 16:49
Show Gist options
  • Save rossmurray/5641553 to your computer and use it in GitHub Desktop.
Save rossmurray/5641553 to your computer and use it in GitHub Desktop.
Generates a random key using an arbitrary character set
void Main()
{
var charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(); //which characters can appear in the string
var length = 32; //length of the string
Console.WriteLine(GenerateKey(charset, length));
}
///Generate a random string of arbitrary length using RNGCryptoServiceProvider.
///characterSet is the set of characters that can appear in the string.
///length is the desired length of string.
public string GenerateKey(char[] characterSet, int length)
{
var result = string.Empty;
using(var rng = new RNGCryptoServiceProvider())
{
while(result.Length < length)
{
var bytes = new byte[4]; //4 bytes in a uint32
rng.GetBytes(bytes);
var value = BitConverter.ToUInt32(bytes, 0);
result += ConvertToBase(value, characterSet);
}
}
return result.Substring(0, length);
}
///Converts a uint to an arbitrary base.
///charset is the characters used to represent the base.
///The length of charset is the base being converted to.
///For example: ConvertToBase(13, new []{'0', '1'}) would convert 13 to base 2 (binary): 1101
public string ConvertToBase(uint value, char[] characterSet)
{
var radix = (uint)characterSet.Length;
if(characterSet == null)
{
throw new ArgumentNullException("charset");
}
if(characterSet.Length < 2)
{
throw new ArgumentException("charset must have at least 2 elements");
}
if(characterSet.Distinct().Count() < characterSet.Length)
{
throw new ArgumentException("charset has duplicate characters");
}
var result = new List<char>();
do
{
var remainder = value % radix;
value = value / radix;
result.Add(characterSet[remainder]);
} while(value > 0); //repeatedly dividing will always reach 0 because: baseN is 2 or greater, and in C#, 1 divided by 2 = 0
result.Reverse();
return new string(result.ToArray());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment