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

sha*_*oth 4 .net c# 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] );
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Mar*_*ell 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);
Run Code Online (Sandbox Code Playgroud)


Noo*_*ilk 5

嗯,这取决于你认为"简单".

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

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