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

我遇到了以下问题:从受限制的字母表中生成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字符串,否则由大写字母和数字组成。 输出看起来不错。

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

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

那么,他怎么会知道种子呢? 除非他知道您运行代码的确切时间,否则很难做到。 但是如果你需要更强大,你也可以通过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); 

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

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

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