Skip to content

Instantly share code, notes, and snippets.

@AydinAdn
Created April 6, 2020 13:45
Show Gist options
  • Save AydinAdn/84d66f0e43f3cfd6f6e7716c09704c0c to your computer and use it in GitHub Desktop.
Save AydinAdn/84d66f0e43f3cfd6f6e7716c09704c0c to your computer and use it in GitHub Desktop.
using System.Linq;
using System.Security.Cryptography;
namespace Cryptography
{
public interface IRSGCryptoService
{
/// <summary>
/// Generates a cryptographically secure string of specified length
/// </summary>
/// <param name="length">Length of the string to be generated</param>
/// <returns>Generated string</returns>
string GenerateString(int length);
}
/// <summary>
/// A cryptographically secure random string generator (RSG)
/// </summary>
public class RSGCryptoService : IRSGCryptoService
{
private readonly char[] charPool;
/// <summary>
/// A cryptographically secure random string generator (RSG)
/// </summary>
public RSGCryptoService()
{
this.charPool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToArray();
}
/// <summary>
/// A cryptographically secure random string generator (RSG)
/// </summary>
/// <param name="charPool">
/// The pool of characters to use
/// when generating a string, overrides
/// the default which contains chars [a-zA-Z0-9]
/// </param>
public RSGCryptoService(char[] charPool)
{
this.charPool = charPool.Distinct().ToArray();
}
/// <summary>
/// Generates a cryptographically secure string of specified length
/// </summary>
/// <param name="length">Length of the string to be generated</param>
/// <returns>Generated string</returns>
public string GenerateString(int length)
{
int maxByteVal = GetMaxByteVal();
string generatedString = "";
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
for (int i = 0; i < length; i++)
{
byte[] bits = new byte[1];
do
{
rng.GetNonZeroBytes(bits);
} while (bits[0] > maxByteVal);
generatedString += charPool[bits[0] % charPool.Length];
}
}
return generatedString;
}
#region Utilities
private int GetMaxByteVal()
{
int multiplier = 256 / charPool.Length;
int maxVal = multiplier * charPool.Length;
return maxVal;
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment