Created
April 6, 2020 13:45
-
-
Save AydinAdn/84d66f0e43f3cfd6f6e7716c09704c0c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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