随机string生成器返回相同的string

我已经开发了一个随机string生成器,但它不像我所希望的那样。 我的目标是能够运行这两次,并生成两个不同的四个字符的随机string。 但是,它只会产生一个四个字符的随机string两次。

以下是代码和输出示例:

private string RandomString(int size) { StringBuilder builder = new StringBuilder(); Random random = new Random(); char ch; for (int i = 0; i < size; i++) { ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))); builder.Append(ch); } return builder.ToString(); } // get 1st random string string Rand1 = RandomString(4); // get 2nd random string string Rand2 = RandomString(4); // create full rand string string docNum = Rand1 + "-" + Rand2; 

…输出看起来像这样:UNTE-UNTE …但它应该看起来像这样的UNTE-FWNU

我怎样才能确保两个明显随机的string?

您在方法中创build了Random实例,这会在快速连续调用时返回相同的值。 我会做这样的事情:

 private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden private string RandomString(int size) { StringBuilder builder = new StringBuilder(); char ch; for (int i = 0; i < size; i++) { ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))); builder.Append(ch); } return builder.ToString(); } // get 1st random string string Rand1 = RandomString(4); // get 2nd random string string Rand2 = RandomString(4); // creat full rand string string docNum = Rand1 + "-" + Rand2; 

(你的代码的修改版本)

你正在实例化你的方法中的Random对象。

Random对象是从系统时钟中接收的 ,这意味着如果你连续多次调用你的方法,它会每次使用相同的种子,这意味着它会产生相同的随机数序列,这意味着你会得到相同的string。

为了解决这个问题,把你的Random实例移到方法本身之外(当你在它的时候,你可以去掉那个疯狂的ConvertFloorNextDouble ):

 private readonly Random _rng = new Random(); private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private string RandomString(int size) { char[] buffer = new char[size]; for (int i = 0; i < size; i++) { buffer[i] = _chars[_rng.Next(_chars.Length)]; } return new string(buffer); } 

//一个非常简单的实现

 using System.IO; public static string RandomStr() { string rStr = Path.GetRandomFileName(); rStr = rStr.Replace(".", ""); // For Removing the . return rStr; } 

//现在只需调用RandomStr()方法

只要您使用Asp.Net 2.0或更高版本,您也可以使用库调用System.Web.Security.Membership.GeneratePassword ,但它将包含特殊字符。

要获得最less为0个特殊字符的4个随机字符 –

 Membership.GeneratePassword(4, 0) 

只是让人们停下来,在一行代码中有什么随机的string

 int yourRandomStringLength = 12; //maximum: 32 Guid.NewGuid().ToString("N").Substring(0, yourRandomStringLength); 

PS:请记住,你的yourRandomStringLength长度不能超过32,因为Guid最大长度为32。

又一个版本的string生成器。 简单,没有花哨的math和魔术数字。 但有一些魔术string指定允许的字符。

更新:我使发电机静态,所以多次调用时不会返回相同的string。 但是这个代码不是 线程安全的 ,绝对不是 密码保护的

对于密码生成,应使用System.Security.Cryptography.RNGCryptoServiceProvider

 private Random _random = new Random(Environment.TickCount); public string RandomString(int length) { string chars = "0123456789abcdefghijklmnopqrstuvwxyz"; StringBuilder builder = new StringBuilder(length); for (int i = 0; i < length; ++i) builder.Append(chars[_random.Next(chars.Length)]); return builder.ToString(); } 

这个解决scheme是Random类的扩展。

用法

 class Program { private static Random random = new Random(); static void Main(string[] args) { random.NextString(10); // "cH*%I\fUWH0" random.NextString(10); // "Cw&N%27+EM" random.NextString(10); // "0LZ}nEJ}_-" random.NextString(); // "kFmeget80LZ}nEJ}_-" } } 

履行

 public static class RandomEx { /// <summary> /// Generates random string of printable ASCII symbols of a given length /// </summary> /// <param name="r">instance of the Random class</param> /// <param name="length">length of a random string</param> /// <returns>Random string of a given length</returns> public static string NextString(this Random r, int length) { var data = new byte[length]; for (int i = 0; i < data.Length; i++) { // All ASCII symbols: printable and non-printable // data[i] = (byte)r.Next(0, 128); // Only printable ASCII data[i] = (byte)r.Next(32, 127); } var encoding = new ASCIIEncoding(); return encoding.GetString(data); } /// <summary> /// Generates random string of printable ASCII symbols /// with random length of 10 to 20 chars /// </summary> /// <param name="r">instance of the Random class</param> /// <returns>Random string of a random length between 10 and 20 chars</returns> public static string NextString(this Random r) { int length = r.Next(10, 21); return NextString(r, length); } } 

这里还有一个选项:

 public System.String GetRandomString(System.Int32 length) { System.Byte[] seedBuffer = new System.Byte[4]; using (var rngCryptoServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider()) { rngCryptoServiceProvider.GetBytes(seedBuffer); System.String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; System.Random random = new System.Random(System.BitConverter.ToInt32(seedBuffer, 0)); return new System.String(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray()); } } 

最好的解决scheme是使用随机数生成器来进行base64转换

 public string GenRandString(int length) { byte[] randBuffer = new byte[length]; RandomNumberGenerator.Create().GetBytes(randBuffer); return System.Convert.ToBase64String(randBuffer).Remove(length); } 

这是因为Random的每个新实例都是从被调用的那么快产生相同的数字。 不要继续创build一个新的实例,只需调用next()并在你的方法之外声明你的随机类。

一个LINQ单线程的好措施(假设一个private static Random Random )…

 public static string RandomString(int length) { return new string(Enumerable.Range(0, length).Select(_ => (char)Random.Next('a', 'z')).ToArray()); } 

您应该在构造函数中启动一个类级别的Random对象,并在每次调用时重用(这将继续伪随机数的相同序列)。 无参数构造函数已经在内部为Environment.TickCount生成了生成器。

我添加了使用Ranvir解决schemeselect长度的选项

 public static string GenerateRandomString(int length) { { string randomString= string.Empty; while (randomString.Length <= length) { randomString+= Path.GetRandomFileName(); randomString= randomString.Replace(".", string.Empty); } return randomString.Substring(0, length); } } 

这里是我对目前接受的答案的修改,我相信这个答案会更快更短一些:

 private static Random random = new Random(); private string RandomString(int size) { StringBuilder builder = new StringBuilder(size); for (int i = 0; i < size; i++) builder.Append((char)random.Next(0x41, 0x5A)); return builder.ToString(); } 

注意我没有使用所有的乘法, Math.floor()Convert

编辑: random.Next(0x41, 0x5A)可以更改为任何范围的Unicode字符。

我的RandomString()方法生成一个随机的string。

 private static readonly Random _rand = new Random(); /// <summary> /// Generate a random string. /// </summary> /// <param name="length">The length of random string. The minimum length is 3.</param> /// <returns>The random string.</returns> public string RandomString(int length) { length = Math.Max(length, 3); byte[] bytes = new byte[length]; _rand.NextBytes(bytes); return Convert.ToBase64String(bytes).Substring(0, length); } 

我想可能这也是可以接受和简单的。

 Guid.NewGuid().ToString() 

如果您想生成一个数字和string作为强密码。

 private static Random random = new Random(); private static string CreateTempPass(int size) { var pass = new StringBuilder(); for (var i=0; i < size; i++) { var binary = random.Next(0,2); switch (binary) { case 0: var ch = (Convert.ToChar(Convert.ToInt32(Math.Floor(26*random.NextDouble() + 65)))); pass.Append(ch); break; case 1: var num = random.Next(1, 10); pass.Append(num); break; } } return pass.ToString(); } 

结合由“Pushcode”和使用随机生成器种子的答案。 我需要它来创build一系列伪可读“单词”。

 private int RandomNumber(int min, int max, int seed=0) { Random random = new Random((int)DateTime.Now.Ticks + seed); return random.Next(min, max); } 

我创build了这个方法。

它工作很好。

 public static string GeneratePassword(int Lenght, int NonAlphaNumericChars) { string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"; string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?"; Random rd = new Random(); if (NonAlphaNumericChars > Lenght || Lenght <= 0 || NonAlphaNumericChars < 0) throw new ArgumentOutOfRangeException(); char[] pass = new char[Lenght]; int[] pos = new int[Lenght]; int i = 0, j = 0, temp = 0; bool flag = false; //Random the position values of the pos array for the string Pass while (i < Lenght - 1) { j = 0; flag = false; temp = rd.Next(0, Lenght); for (j = 0; j < Lenght; j++) if (temp == pos[j]) { flag = true; j = Lenght; } if (!flag) { pos[i] = temp; i++; } } //Random the AlphaNumericChars for (i = 0; i < Lenght - NonAlphaNumericChars; i++) pass[i] = allowedChars[rd.Next(0, allowedChars.Length)]; //Random the NonAlphaNumericChars for (i = Lenght - NonAlphaNumericChars; i < Lenght; i++) pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)]; //Set the sorted array values by the pos array for the rigth posistion char[] sorted = new char[Lenght]; for (i = 0; i < Lenght; i++) sorted[i] = pass[pos[i]]; string Pass = new String(sorted); return Pass; } 

这是基于GUID的另一个想法。 我已经使用Visual Studio性能testing来生成只包含字母数字字符的随机string。

 public string GenerateRandomString(int stringLength) { Random rnd = new Random(); Guid guid; String randomString = string.Empty; int numberOfGuidsRequired = (int)Math.Ceiling((double)stringLength / 32d); for (int i = 0; i < numberOfGuidsRequired; i++) { guid = Guid.NewGuid(); randomString += guid.ToString().Replace("-", ""); } return randomString.Substring(0, stringLength); } 

这里是一个博客文章 ,提供了一个更强大的类生成随机单词,句子和段落。

 public static class StringHelpers { public static readonly Random rnd = new Random(); public static readonly string EnglishAlphabet = "abcdefghijklmnopqrstuvwxyz"; public static readonly string RussianAlphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"; public static unsafe string GenerateRandomUTF8String(int length, string alphabet) { if (length <= 0) return String.Empty; if (string.IsNullOrWhiteSpace(alphabet)) throw new ArgumentNullException("alphabet"); byte[] randomBytes = rnd.NextBytes(length); string s = new string(alphabet[0], length); fixed (char* p = s) { for (int i = 0; i < s.Length; i++) { *(p + i) = alphabet[randomBytes[i] % alphabet.Length]; } } return s; } public static unsafe string GenerateRandomUTF8String(int length, params UnicodeCategory[] unicodeCategories) { if (length <= 0) return String.Empty; if (unicodeCategories == null) throw new ArgumentNullException("unicodeCategories"); if (unicodeCategories.Length == 0) return rnd.NextString(length); byte[] randomBytes = rnd.NextBytes(length); string s = randomBytes.ConvertToString(); fixed (char* p = s) { for (int i = 0; i < s.Length; i++) { while (!unicodeCategories.Contains(char.GetUnicodeCategory(*(p + i)))) *(p + i) += (char)*(p + i); } } return s; } } 

你也需要这个:

 public static class RandomExtensions { public static string NextString(this Random rnd, int length) { if (length <= 0) return String.Empty; return rnd.NextBytes(length).ConvertToString(); } public static byte[] NextBytes(this Random rnd, int length) { if (length <= 0) return new byte[0]; byte[] randomBytes = new byte[length]; rnd.NextBytes(randomBytes); return randomBytes; } } 

和这个:

 public static class ByteArrayExtensions { public static string ConvertToString(this byte[] bytes) { if (bytes.Length <= 0) return string.Empty; char[] chars = new char[bytes.Length / sizeof(char)]; Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length); return new string(chars); } } 

实际上,一个好的解决scheme是为线程安全的随机数生成器提供静态方法,而不使用锁。

这样,多个用户同时访问您的Web应用程序不会得到相同的随机string。

这里有3个例子: http : //blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx

我会用最后一个:

 public static class RandomGen3 { private static RNGCryptoServiceProvider _global = new RNGCryptoServiceProvider(); [ThreadStatic] private static Random _local; public static int Next() { Random inst = _local; if (inst == null) { byte[] buffer = new byte[4]; _global.GetBytes(buffer); _local = inst = new Random( BitConverter.ToInt32(buffer, 0)); } return inst.Next(); } } 

那么你可以适当消除

 Random random = new Random(); 

只要调用RandomGen3.Next(),而你的方法可以保持静态。

对于随机串生成器:

 #region CREATE RANDOM STRING WORD char[] wrandom = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','R','S','T','U','V','X','W','Y','Z'}; Random random = new Random(); string random_string = ""; int count = 12; //YOU WILL SPECIFY HOW MANY CHARACTER WILL BE GENERATE for (int i = 0; i < count; i++ ) { random_string = random_string + wrandom[random.Next(0, 24)].ToString(); } MessageBox.Show(random_string); #endregion 

我发现这样做更有帮助,因为它是一个扩展,它允许您select代码的来源。

 static string numbers = "0123456789", letters = "abcdefghijklmnopqrstvwxyz", lettersUp = letters.ToUpper(), codeAll = numbers + letters + lettersUp; static Random m_rand = new Random(); public static string GenerateCode(this int size) { return size.GenerateCode(CodeGeneratorType.All); } public static string GenerateCode(this int size, CodeGeneratorType type) { string source; if (type == CodeGeneratorType.All) { source = codeAll; } else { StringBuilder sourceBuilder = new StringBuilder(); if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Numbers) sourceBuilder.Append(numbers); if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.Letters) sourceBuilder.Append(letters); if ((type & CodeGeneratorType.Letters) == CodeGeneratorType.LettersUpperCase) sourceBuilder.Append(lettersUp); source = sourceBuilder.ToString(); } return size.GenerateCode(source); } public static string GenerateCode(this int size, string source) { StringBuilder code = new StringBuilder(); int maxIndex = source.Length-1; for (int i = 0; i < size; i++) { code.Append(source[Convert.ToInt32(Math.Round(m_rand.NextDouble() * maxIndex))]); } return code.ToString(); } public enum CodeGeneratorType { Numbers = 1, Letters = 2, LettersUpperCase = 4, All = 16 }; 

希望这可以帮助。

在我的情况下,密码必须包含:

  • 至less有一个小写字母。
  • 至less有一个大写字母。
  • 至less有一个小数。
  • 至less有一个特殊字符。

这是我的代码:

  private string CreatePassword(int len) { string[] valid = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890", "!@#$%^&*()_+" }; RNGCryptoServiceProvider rndGen = new RNGCryptoServiceProvider(); byte[] random = new byte[len]; int[] selected = new int[len]; do { rndGen.GetNonZeroBytes(random); for (int i = 0; i < random.Length; i++) { selected[i] = random[i] % 4; } } while(selected.Distinct().Count() != 4); rndGen.GetNonZeroBytes(random); string res = ""; for(int i = 0; i<len; i++) { res += valid[selected[i]][random[i] % valid[selected[i]].Length]; } return res; } 

你好
您可以使用MMLib.RapidPrototyping nuget包中的WordGenerator或LoremIpsumGenerator。

 using MMLib.RapidPrototyping.Generators; public void WordGeneratorExample() { WordGenerator generator = new WordGenerator(); var randomWord = generator.Next(); Console.WriteLine(randomWord); } 

Nuget网站
Codeplex项目网站

如果您有权访问兼容英特尔安全密钥的CPU,则可以使用这些库生成真正的随机数字和string: https : //github.com/JebteK/RdRand和https://www.rdrand.com/

只需从这里下载最新版本,包括Jebtek.RdRand并为其添加使用语句。 那么,你需要做的是这样的:

 bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU string key = RdRandom.GenerateKey(10); //Generate 10 random characters 

另外,您还可以获得这些附加function:

 string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int 

如果您没有兼容的CPU来执行代码,只需使用rdrand.com上的RESTful服务即可。 使用您的项目中包含的RdRandom包装器库,您只需要执行此操作(注册时可以获得1000个免费调用):

 string ret = Randomizer.GenerateKey(<length>, "<key>"); 

您也可以如下生成随机字节数组和无符号整数:

 uint ret = Randomizer.GenerateUInt("<key>"); byte[] ret = Randomizer.GenerateBytes(<length>, "<key>"); 

另一个样本(vs2013testing):

  Random R = new Random(); public static string GetRandomString(int Length) { char[] ArrRandomChar = new char[Length]; for (int i = 0; i < Length; i++) ArrRandomChar[i] = (char)('a' + R.Next(0, 26)); return new string(ArrRandomChar); } string D = GetRandomString(12); 

由我自己执行。

这是我的解决scheme:

 private string RandomString(int length) { char[] symbols = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; Stack<byte> bytes = new Stack<byte>(); string output = string.Empty; for (int i = 0; i < length; i++) { if (bytes.Count == 0) { bytes = new Stack<byte>(Guid.NewGuid().ToByteArray()); } byte pop = bytes.Pop(); output += symbols[(int)pop % symbols.Length]; } return output; } // get 1st random string string Rand1 = RandomString(4); // get 2nd random string string Rand2 = RandomString(4); // create full rand string string docNum = Rand1 + "-" + Rand2;