代码之家  ›  专栏  ›  技术社区  ›  sharptooth

如何在C程序中生成一组随机字符串,使它们不被琐碎的预测?

  •  4
  • sharptooth  · 技术社区  · 14 年前

    我面临以下问题:从受限字母表生成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] );
    }
    

    它生成以“prefix”开头的10000个字符串,或者由大写字母和数字组成。输出看起来不错。

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

    是否可以对我的代码进行一些简单的更改以降低所描述的攻击的可能性?

    2 回复  |  直到 14 年前
        1
  •  7
  •   Marc Gravell    14 年前

    嗯,他怎么知道种子的?除非他知道 确切时间 你运行了代码,就是 非常 很难做到。但是如果你需要更强的,你也可以通过 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);
    
        2
  •  5
  •   Noon Silk    14 年前

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

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

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