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 attempt 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With