Reputation: 11806
I'm new to .NET and C# and I'm trying to figure out how this code works:
public static string CreateRandomPassword(int PasswordLength)
{
String _allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ23456789";
Byte[] randomBytes = new Byte[PasswordLength];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
char[] chars = new char[PasswordLength];
int allowedCharCount = _allowedChars.Length;
for(int i = 0;i<PasswordLength;i++)
{
///
/// I don't understand how this line works:
///
chars[i] = _allowedChars[(int)randomBytes[i] % allowedCharCount];
}
return new string(chars);
}
I think I've got a pretty good handle on most of this. I haven't been able to understand the following line:
chars[i] = _allowedChars[(int)randomBytes[i] % allowedCharCount];
I understand that the code generates random binary numbers and uses those random numbers in the for loop to select a character from the _allowedChars string. What I don't get is why this code uses the modulous operator (%) to get the _allowedChars index value.
Thanks for any help
Upvotes: 1
Views: 918
Reputation: 1
2%5=3
4%5=1
6%5=1
15%5=0
16%5=1
That guarantees any result between 0-5.
If you replace 5 with any other number (n), you'll have a similar guarantee that the result will be between 0-n.
Upvotes: -1
Reputation: 416039
This is only a side note, but that code is subtly broken. The modulus operator (%) used to select which character to pick is not uniform: it's going to prefer some characters (those nearer the front of the array) more than others, meaning the password is not truly random. An attacker can use that to try higher-probability passwords first, and significantly reduce the time it takes to complete a crack.
Upvotes: 6
Reputation: 137158
It uses the modulus operator because randomBytes[i]
could hold a value larger than the length of the _allowedChars
array.
By using % allowedCharCount
it ensures that the index into _allowedChars
is always within range. Otherwise the code would have the potential to raise an exception on that line.
Upvotes: 0
Reputation: 26668
The value of randomBytes[i] can be any integer from 0 through 255. The length of the _allowedChars array is less than 255. The modules operator returns the remainder of dividing the first argument ((int)randomBytes[i]) by the second argument (allowedCharCount). This ensures that the value we index the _allowedChars array with (the result of the modulo operator) is always less than the allowedCharacterCount.
Upvotes: 3
Reputation: 34218
Using mod ensures that the number is between 0 and allowedCharCount
- it prevents an index out of range exception. Without it, you'd have to restrict the range of the randomly generated numbers, which isn't possible with the crypto provider. It also means that you can change the list of allowed characters in the string without the code breaking.
Upvotes: 0
Reputation: 40202
You're working modulo allowedCharCount
, this ensure that the number generated is between 0 and allowedCharCount
so that no IndexOutOfRange
exception is thrown.
Upvotes: 0