private static Random random = new Random();
public static string RandomString(int length){const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());}
框架支持-. NET Core 3(以及支持. NET Standard 2.1或更高版本的未来平台)提供了一种加密可靠的方法随机数生成器。进入t 32()来生成所需范围内的随机整数。
与提出的一些替代方案不同,这个是加密声音。
using System;using System.Security.Cryptography;using System.Text;
namespace UniqueKey{public class KeyGenerator{internal static readonly char[] chars ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
public static string GetUniqueKey(int size){byte[] data = new byte[4*size];using (var crypto = RandomNumberGenerator.Create()){crypto.GetBytes(data);}StringBuilder result = new StringBuilder(size);for (int i = 0; i < size; i++){var rnd = BitConverter.ToUInt32(data, i * 4);var idx = rnd % chars.Length;
result.Append(chars[idx]);}
return result.ToString();}
public static string GetUniqueKeyOriginal_BIASED(int size){char[] chars ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();byte[] data = new byte[size];using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()){crypto.GetBytes(data);}StringBuilder result = new StringBuilder(size);foreach (byte b in data){result.Append(chars[b % (chars.Length)]);}return result.ToString();}}}
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";var stringChars = new char[8];var random = new Random();
for (int i = 0; i < stringChars.Length; i++){stringChars[i] = chars[random.Next(chars.Length)];}
var finalString = new String(stringChars);
static char[] charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();static int byteSize = 256; //Labelling conveniencestatic int biasZone = byteSize - (byteSize % charSet.Length);public string GenerateRandomString(int Length) //Configurable output string length{byte[] rBytes = new byte[Length]; //Do as much before and after lock as possiblechar[] rName = new char[Length];SecureFastRandom.GetNextBytesMax(rBytes, biasZone);for (var i = 0; i < Length; i++){rName[i] = charSet[rBytes[i] % charSet.Length];}return new string(rName);}
但是你需要我的新(未测试)类:
/// <summary>/// My benchmarking showed that for RNGCryptoServiceProvider:/// 1. There is negligable benefit of sharing RNGCryptoServiceProvider object reference/// 2. Initial GetBytes takes 2ms, and an initial read of 1MB takes 3ms (starting to rise, but still negligable)/// 2. Cached is ~1000x faster for single byte at a time - taking 9ms over 1MB vs 989ms for uncached/// </summary>class SecureFastRandom{static byte[] byteCache = new byte[1000000]; //My benchmark showed that an initial read takes 2ms, and an initial read of this size takes 3ms (starting to raise)static int lastPosition = 0;static int remaining = 0;
/// <summary>/// Static direct uncached access to the RNGCryptoServiceProvider GetBytes function/// </summary>/// <param name="buffer"></param>public static void DirectGetBytes(byte[] buffer){using (var r = new RNGCryptoServiceProvider()){r.GetBytes(buffer);}}
/// <summary>/// Main expected method to be called by user. Underlying random data is cached from RNGCryptoServiceProvider for best performance/// </summary>/// <param name="buffer"></param>public static void GetBytes(byte[] buffer){if (buffer.Length > byteCache.Length){DirectGetBytes(buffer);return;}
lock (byteCache){if (buffer.Length > remaining){DirectGetBytes(byteCache);lastPosition = 0;remaining = byteCache.Length;}
Buffer.BlockCopy(byteCache, lastPosition, buffer, 0, buffer.Length);lastPosition += buffer.Length;remaining -= buffer.Length;}}
/// <summary>/// Return a single byte from the cache of random data./// </summary>/// <returns></returns>public static byte GetByte(){lock (byteCache){return UnsafeGetByte();}}
/// <summary>/// Shared with public GetByte and GetBytesWithMax, and not locked to reduce lock/unlocking in loops. Must be called within lock of byteCache./// </summary>/// <returns></returns>static byte UnsafeGetByte(){if (1 > remaining){DirectGetBytes(byteCache);lastPosition = 0;remaining = byteCache.Length;}
lastPosition++;remaining--;return byteCache[lastPosition - 1];}
/// <summary>/// Rejects bytes which are equal to or greater than max. This is useful for ensuring there is no bias when you are modulating with a non power of 2 number./// </summary>/// <param name="buffer"></param>/// <param name="max"></param>public static void GetBytesWithMax(byte[] buffer, byte max){if (buffer.Length > byteCache.Length / 2) //No point caching for larger sizes{DirectGetBytes(buffer);
lock (byteCache){UnsafeCheckBytesMax(buffer, max);}}else{lock (byteCache){if (buffer.Length > remaining) //Recache if not enough remaining, discarding remaining - too much work to join two blocksDirectGetBytes(byteCache);
Buffer.BlockCopy(byteCache, lastPosition, buffer, 0, buffer.Length);lastPosition += buffer.Length;remaining -= buffer.Length;
UnsafeCheckBytesMax(buffer, max);}}}
/// <summary>/// Checks buffer for bytes equal and above max. Must be called within lock of byteCache./// </summary>/// <param name="buffer"></param>/// <param name="max"></param>static void UnsafeCheckBytesMax(byte[] buffer, byte max){for (int i = 0; i < buffer.Length; i++){while (buffer[i] >= max)buffer[i] = UnsafeGetByte(); //Replace all bytes which are equal or above max}}}
对于历史-我对这个答案的旧解决方案,使用Random对象:
private static char[] charSet ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();
static rGen = new Random(); //Must share, because the clock seed only has Ticks (~10ms) resolution, yet lock has only 20-50ns delay.static int byteSize = 256; //Labelling conveniencestatic int biasZone = byteSize - (byteSize % charSet.Length);static bool SlightlyMoreSecurityNeeded = true; //Configuration - needs to be true, if more security is desired and if charSet.Length is not divisible by 2^X.public string GenerateRandomString(int Length) //Configurable output string length{byte[] rBytes = new byte[Length]; //Do as much before and after lock as possiblechar[] rName = new char[Length];lock (rGen) //~20-50ns{rGen.NextBytes(rBytes);
for (int i = 0; i < Length; i++){while (SlightlyMoreSecurityNeeded && rBytes[i] >= biasZone) //Secure against 1/5 increased bias of index[0-7] values against others. Note: Must exclude where it == biasZone (that is >=), otherwise there's still a bias on index 0.rBytes[i] = rGen.NextByte();rName[i] = charSet[rBytes[i] % charSet.Length];}}return new string(rName);}
using System;using System.Security.Cryptography;
public static string GetRandomAlphanumericString(int length){const string alphanumericCharacters ="ABCDEFGHIJKLMNOPQRSTUVWXYZ" +"abcdefghijklmnopqrstuvwxyz" +"0123456789";return GetRandomString(length, alphanumericCharacters);}
public static string GetRandomString(int length, IEnumerable<char> characterSet){if (length < 0)throw new ArgumentException("length must not be negative", "length");if (length > int.MaxValue / 8) // 250 million chars ought to be enough for anybodythrow new ArgumentException("length is too big", "length");if (characterSet == null)throw new ArgumentNullException("characterSet");var characterArray = characterSet.Distinct().ToArray();if (characterArray.Length == 0)throw new ArgumentException("characterSet must not be empty", "characterSet");
var bytes = new byte[length * 8];var result = new char[length];using (var cryptoProvider = new RNGCryptoServiceProvider()){cryptoProvider.GetBytes(bytes);}for (int i = 0; i < length; i++){ulong value = BitConverter.ToUInt64(bytes, i * 8);result[i] = characterArray[value % (uint)characterArray.Length];}return new string(result);}
public static string GetRandomAlphaNumeric(){var chars = 'a'.To('z').Concat('0'.To('9')).ToList();return new string(chars.Select(c => chars[random.Next(chars.Length)]).Take(8).ToArray());}
public static IEnumerable<char> To(this char start, char end){if (end < start)throw new ArgumentOutOfRangeException("the end char should not be less than start char", innerException: null);return Enumerable.Range(start, end - start + 1).Select(i => (char)i);}
public static class StringHelper{private static readonly Random random = new Random();
private const int randomSymbolsDefaultCount = 8;private const string availableChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static int randomSymbolsIndex = 0;
public static string GetRandomSymbols(){return GetRandomSymbols(randomSymbolsDefaultCount);}
public static string GetRandomSymbols(int count){var index = randomSymbolsIndex;var result = new string(Enumerable.Repeat(availableChars, count).Select(s => {index += random.Next(s.Length);if (index >= s.Length)index -= s.Length;return s[index];}).ToArray());randomSymbolsIndex = index;return result;}}
public static string Random(this string chars, int length = 8){var randomString = new StringBuilder();var random = new Random();
for (int i = 0; i < length; i++)randomString.Append(chars[random.Next(chars.Length)]);
return randomString.ToString();}
用法
var random = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Random();
或
var random = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".Random(16);
string str = Path.GetRandomFileName(); //This method returns a random file name of 11 charactersstr = str.Replace(".","");Console.WriteLine("Random string: " + str);
public class RandomStringGenerator{public static string Gen(){return ConvertToBase(DateTime.UtcNow.ToFileTimeUtc()) + GenRandomStrings(5); //keep length fixed at least of one part}
private static string GenRandomStrings(int strLen){var result = string.Empty;
using (var gen = new RNGCryptoServiceProvider()){var data = new byte[1];
while (result.Length < strLen){gen.GetNonZeroBytes(data);int code = data[0];if (code > 48 && code < 57 || // 0-9code > 65 && code < 90 || // A-Zcode > 97 && code < 122 // a-z){result += Convert.ToChar(code);}}
return result;}}
private static string ConvertToBase(long num, int nbase = 36){const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //if you wish to make the algorithm more secure - change order of letter here
// check if we can convert to another baseif (nbase < 2 || nbase > chars.Length)return null;
int r;var newNumber = string.Empty;
// in r we have the offset of the char that was converted to the new basewhile (num >= nbase){r = (int)(num % nbase);newNumber = chars[r] + newNumber;num = num / nbase;}// the last number to convertnewNumber = chars[(int)num] + newNumber;
return newNumber;}}
void Main(){Random rnd = new Random();rnd.GetString("1-###-000").Dump();}
public static class RandomExtensions{public static string GetString(this Random random, string format){// Based on http://stackoverflow.com/questions/1344221/how-can-i-generate-random-alphanumeric-strings-in-c// Added logic to specify the format of the random string (# will be random string, 0 will be random numeric, other characters remain)StringBuilder result = new StringBuilder();for(int formatIndex = 0; formatIndex < format.Length ; formatIndex++){switch(format.ToUpper()[formatIndex]){case '0': result.Append(getRandomNumeric(random)); break;case '#': result.Append(getRandomCharacter(random)); break;default : result.Append(format[formatIndex]); break;}}return result.ToString();}
private static char getRandomCharacter(Random random){string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";return chars[random.Next(chars.Length)];}
private static char getRandomNumeric(Random random){string nums = "0123456789";return nums[random.Next(nums.Length)];}}
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";var random = new Random();var list = Enumerable.Repeat(0, 8).Select(x=>chars[random.Next(chars.Length)]);return string.Join("", list);
public static class UsernameTools{public static string GenerateRandomUsername(int length = 10){Random random = new Random();StringBuilder sbuilder = new StringBuilder();for (int x = 0; x < length; ++x){sbuilder.Append((char)random.Next(33, 126));}return sbuilder.ToString();}
}
var chars = Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 8);
var randomStr = new string(chars.SelectMany(str => str).OrderBy(c => Guid.NewGuid()).Take(8).ToArray());
public static string GetUniqueKey(int size = 6, string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"){using (var crypto = new RNGCryptoServiceProvider()){var data = new byte[size];
// 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 bufferbyte[] smallBuffer = null;
// Maximum random number that can be used without introducing a// biasint maxRandom = byte.MaxValue - ((byte.MaxValue + 1) % chars.Length);
crypto.GetBytes(data);
var result = new char[size];
for (int i = 0; i < size; i++){byte v = data[i];
while (v > maxRandom){if (smallBuffer == null){smallBuffer = new byte[1];}
crypto.GetBytes(smallBuffer);v = smallBuffer[0];}
result[i] = chars[v % chars.Length];}
return new string(result);}}
以下是Eric J的解决方案的变体,即用于WinRT(Windows Store App)的加密声音:
public static string GenerateRandomString(int length){var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";var result = new StringBuilder(length);for (int i = 0; i < length; ++i){result.Append(CryptographicBuffer.GenerateRandomNumber() % chars.Length);}return result.ToString();}
如果性能很重要(特别是当长度很高时):
public static string GenerateRandomString(int length){var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";var result = new System.Text.StringBuilder(length);var bytes = CryptographicBuffer.GenerateRandom((uint)length * 4).ToArray();for (int i = 0; i < bytes.Length; i += 4){result.Append(BitConverter.ToUInt32(bytes, i) % chars.Length);}return result.ToString();}
public static string RandomString(int length){const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";var random = new Random();return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());}
private static Random random = new Random();public static string Random(int length){var stringChars = new char[length];
for (int i = 0; i < length; i++){stringChars[i] = (char)random.Next(0x30, 0x7a);return new string(stringChars);}}
public static string GenerateRandomString(int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") =>new Random().GenerateRandomString(length, charset);
public static string GenerateRandomString(this Random random, int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") =>RandomString(random.NextBytes, length, charset.ToCharArray());
public static string GenerateRandomCryptoString(int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"){using (var crypto = new System.Security.Cryptography.RNGCryptoServiceProvider())return crypto.GenerateRandomCryptoString(length, charset);}
public static string GenerateRandomCryptoString(this RNGCryptoServiceProvider random, int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") =>RandomString(random.GetBytes, length, charset.ToCharArray());
private static string RandomString(Action<byte[]> fillRandomBuffer, int length, char[] charset){if (length < 0)throw new ArgumentOutOfRangeException(nameof(length), $"{nameof(length)} must be greater or equal to 0");if (charset is null)throw new ArgumentNullException(nameof(charset));if (charset.Length == 0)throw new ArgumentException($"{nameof(charset)} must contain at least 1 character", nameof(charset));
var maxIdx = charset.Length;var chars = new char[length];var randomBuffer = new byte[length * 4];fillRandomBuffer(randomBuffer);
for (var i = 0; i < length; i++)chars[i] = charset[BitConverter.ToUInt32(randomBuffer, i * 4) % maxIdx];
return new string(chars);}
使用生成器和LINQ。不是最快的选择(特别是因为它不会一次性生成所有字节),但非常整洁且可扩展:
private static readonly Random _random = new Random();
public static string GenerateRandomString(int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") =>new string(_random.GetGenerator().RandomChars(charset.ToCharArray()).Take(length).ToArray());
public static string GenerateRandomCryptoString(int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"){using (var crypto = new System.Security.Cryptography.RNGCryptoServiceProvider())return new string(crypto.GetGenerator().RandomChars(charset.ToCharArray()).Take(length).ToArray());}
public static IEnumerable<char> RandomChars(this Func<uint, IEnumerable<uint>> randomGenerator, char[] charset){if (charset is null)throw new ArgumentNullException(nameof(charset));if (charset.Length == 0)throw new ArgumentException($"{nameof(charset)} must contain at least 1 character", nameof(charset));
return randomGenerator((uint)charset.Length).Select(r => charset[r]);}
public static Func<uint, IEnumerable<uint>> GetGenerator(this Random random){if (random is null)throw new ArgumentNullException(nameof(random));
return GeneratorFunc_Inner;
IEnumerable<uint> GeneratorFunc_Inner(uint maxValue){if (maxValue > int.MaxValue)throw new ArgumentOutOfRangeException(nameof(maxValue));
return Generator_Inner();
IEnumerable<uint> Generator_Inner(){var randomBytes = new byte[4];while (true){random.NextBytes(randomBytes);yield return BitConverter.ToUInt32(randomBytes, 0) % maxValue;}}}}
public static Func<uint, IEnumerable<uint>> GetGenerator(this System.Security.Cryptography.RNGCryptoServiceProvider random){if (random is null)throw new ArgumentNullException(nameof(random));
return Generator_Inner;
IEnumerable<uint> Generator_Inner(uint maxValue){var randomBytes = new byte[4];while (true){random.GetBytes(randomBytes);yield return BitConverter.ToUInt32(randomBytes, 0) % maxValue;}}}
一个更简单的版本,仅对非加密字符串使用LINQ:
private static readonly Random _random = new Random();
public static string RandomString(int length, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") =>new string(_random.GenerateChars(charset).Take(length).ToArray());
public static IEnumerable<char> GenerateChars(this Random random, string charset){if (charset is null) throw new ArgumentNullException(nameof(charset));if (charset.Length == 0) throw new ArgumentException($"{nameof(charset)} must contain at least 1 character", nameof(charset));
return random.Generator(charset.Length).Select(r => charset[r]);}
public static IEnumerable<int> Generator(this Random random, int maxValue){if (random is null) throw new ArgumentNullException(nameof(random));
return Generator_Inner();
IEnumerable<int> Generator_Inner() { while (true) yield return random.Next(maxValue); }}
public static string GenerateRandomString(int length, IEnumerable<char> charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"){var charArray = charSet.Distinct().ToArray();char[] result = new char[length];for (int i = 0; i < length; i++)result[i] = charArray[RandomNumberGenerator.GetInt32(charArray.Length)];return new string(result);}