如何在C#程序中生成一组随机字符串,以便不进行简单的预测?

时间:2010-07-22 09:05:24

标签: c# .net random

我遇到了以下问题:从受限制的字母表中生成N个唯一的字母数字字符串。这是我在C#中的解决方案:

string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random generator = new Random();
const int ToGenerate = 10000;
const int CharactersCount = 4;
ArrayList generatedStrings = new ArrayList();
while( generatedStrings.Count < ToGenerate ) {
   string newString = "Prefix";
   for( int i = 0; i < CharactersCount; i++ ) {
      int index = generator.Next( Alphabet.Length );
      char character = Alphabet[index];
      newString += character;
   }
   if( !generatedStrings.Contains( newString ) ) {
      generatedStrings.Add( newString );
   }                
}
for( int i = 0; i < generatedStrings.Count; i++ ) {
    System.Console.Out.WriteLine( generatedStrings[i] );
}

它生成以“前缀”开头的10K字符串,否则由大写字母和数字组成。输出看起来不错。

现在我看到以下问题。生成的字符串用于不太可能被任何人预测的情况。在我的计划中,种子是时间依赖的。一旦有人知道种子值,他就可以运行相同的代码并获得完全相同的字符串。如果他知道任何两个字符串,他可以很容易地找出我的算法(因为它真的很天真)并尝试暴力破坏种子值 - 只需枚举所有可能的种子值,直到他看到输出中的两个已知字符串。

是否可以对我的代码进行一些简单的更改,以减少所描述的攻击?

2 个答案:

答案 0 :(得分:7)

嗯,他怎么会知道种子?除非他知道准确时间你运行了代码,否则非常很难做到。但是如果你需要更强大,你也可以通过System.Security.Cryptography.RandomNumberGenerator.Create创建加密强大的随机数 - 例如:

        var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
        byte[] buffer = new byte[4];
        char[] chars = new char[CharactersCount];
        for(int i = 0 ; i < chars.Length ; i++)
        {
            rng.GetBytes(buffer);
            int nxt = BitConverter.ToInt32(buffer, 0);
            int index = nxt % Alphabet.Length;
            if(index < 0) index += Alphabet.Length;
            chars[i] = Alphabet[index];
        }
        string s = new string(chars);

答案 1 :(得分:5)

嗯,这取决于你认为“简单”。

您可以使用“真实”的随机数源“解决”您的问题。您可以尝试免费的(random.org,fourmilab hotbits等)或buy one,具体取决于您正在运行的操作类型。

或者(也许更好)是不提前生成,而是按需生成。但这可能是对您的业务流程/模型的重大改变。