开发者

How do I generate a set of random strings in a C# program so that they are not trivially predicted?

I faced a following problem: generate N unique alphanumeric strings from a restricted alphabet. Here's my solution in 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] );
}

it generates 10K strings starting with "Prefix" and otherwise consisting of capital letters and numbers. The output looks good.

Now I see the following problem. The produced strings are for a scenario where they should be unlikely to be predicted by anyone. In my program the seed is time-dependent. Once someone knows the seed value he can run the same code and get the exact same strings. If he knows any two strings he can easily figure out my algorithm (since it is really naive) and a开发者_运维技巧ttempt to brute-force the seed value - just enumerate all possible seed values until he sees the two known strings in the output.

Is there some simple change that could be done to my code to make the described attack less possible?


Well, how would he know the seed? Unless he knew the exact time you ran the code, that is very hard to do. But if you need stronger, you can also create cryptographically strong random numbers via System.Security.Cryptography.RandomNumberGenerator.Create - something like:

        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);


Well, it depends what you consider "simple".

You can "solve" your problem by using a "true" source of random numbers. You can try the free ones (random.org, fourmilab hotbits, etc), or buy one, depending on the sort of operation you're running.

Alternatively (and perhaps better) is to not generate in advance, and instead generate on demand. But this may be a significant change to your business process/model.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜