C# 随机字符串生成器返回相同的字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1122483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Random String Generator Returning Same String
提问by PushCode
I've developed a random string generator but it's not behaving quite as I'm hoping. My goal is to be able to run this twice and generate two distinct four character random strings. However, it just generates one four character random string twice.
我开发了一个随机字符串生成器,但它的表现并不像我希望的那样。我的目标是能够运行两次并生成两个不同的四个字符的随机字符串。但是,它只是两次生成一个四字符的随机字符串。
Here's the code and an example of its output:
这是代码及其输出示例:
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;
...and the output looks like this: UNTE-UNTE ...but it should look something like this UNTE-FWNU
...输出看起来像这样:UNTE-UNTE ...但它应该看起来像这样 UNTE-FWNU
How can I ensure two distinctly random strings?
如何确保两个明显随机的字符串?
采纳答案by RCIX
You're making the Random instance in the method, which causes it to return the same values when called in quick succession. I would do something like this:
您正在方法中创建 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;
(modified version of your code)
(您的代码的修改版本)
回答by LukeH
You're instantiating the Random
object inside your method.
您正在方法中实例化Random
对象。
The Random
object is seeded from the system clock, which means that if you call your method several times in quick succession it'll use the same seed each time, which means that it'll generate the same sequence of random numbers, which means that you'll get the same string.
该Random
对象是从系统时钟作为种子的,这意味着如果您快速连续多次调用您的方法,它每次将使用相同的种子,这意味着它将生成相同的随机数序列,这意味着您将得到相同的字符串。
To solve the problem, move your Random
instance outside of the method itself (and while you're at it you could get rid of that crazy sequence of calls to Convert
and Floor
and NextDouble
):
要解决这个问题,请将您的Random
实例移到方法本身之外(当您使用它时,您可以摆脱对Convert
andFloor
和 and 的疯狂调用序列NextDouble
):
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);
}
回答by John T
This is because each new instance of Random is generating the same numbers from being called so fast. Do notkeep creating a new instance, just call next() and declare your random class outside of your method.
这是因为 Random 的每个新实例都因为被如此快地调用而生成相同的数字。不要继续创建新实例,只需调用 next() 并在方法之外声明您的随机类。
回答by Kenan E. K.
You should have one class-level Random object initiated once in the constructor and reused on each call (this continues the same sequence of pseudo-random numbers). The parameterless constructor already seeds the generator with Environment.TickCount internally.
您应该在构造函数中初始化一个类级别的 Random 对象,并在每次调用时重复使用(这会继续使用相同的伪随机数序列)。无参数构造函数已经在内部使用 Environment.TickCount 为生成器提供种子。
回答by Nick Olsen
Here is a blog postthat provides a bit more robust class for generating random words, sentences and paragraphs.
这是一篇博客文章,它提供了一个更强大的类来生成随机单词、句子和段落。
回答by CGsoldier
If you wanted to generate a string of Numbers and Characters for a strong password.
如果您想为强密码生成一串数字和字符。
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();
}
回答by Ranvir
//A very Simple implementation
//一个非常简单的实现
using System.IO;
public static string RandomStr()
{
string rStr = Path.GetRandomFileName();
rStr = rStr.Replace(".", ""); // For Removing the .
return rStr;
}
//Now just call RandomStr() Method
//现在只需调用RandomStr()方法
回答by Spongeboy
As long as you are using Asp.Net 2.0 or greater, you can also use the library call-
System.Web.Security.Membership.GeneratePassword
, however it will include special characters.
只要您使用的是 Asp.Net 2.0 或更高版本,您也可以使用库 call-
System.Web.Security.Membership.GeneratePassword
,但它会包含特殊字符。
To get 4 random characters with minimum of 0 special characters-
要获得至少 0 个特殊字符的 4 个随机字符-
Membership.GeneratePassword(4, 0)
回答by Ideogram
Combining the answer by "Pushcode" and the one using the seed for the random generator. I needed it to create a serie of pseudo-readable 'words'.
将“Pushcode”的答案和使用随机生成器的种子的答案结合起来。我需要它来创建一系列伪可读的“单词”。
private int RandomNumber(int min, int max, int seed=0)
{
Random random = new Random((int)DateTime.Now.Ticks + seed);
return random.Next(min, max);
}
回答by oleksii
This solution is an extension for a Random
class.
这个解决方案是一个Random
类的扩展。
Usage
用法
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}_-"
}
}
Implementation
执行
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);
}
}