yeomandev
yeomandev

Reputation: 11806

How does this C# asp.net random password code work?

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

Answers (6)

mohamed
mohamed

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

Joel Coehoorn
Joel Coehoorn

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

ChrisF
ChrisF

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

quentin-starin
quentin-starin

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

Dan Puzey
Dan Puzey

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

Omar
Omar

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

Related Questions