开发者

How does BasePage.GeneratePassword in .net works?

I am using BasePage.GeneratePassword(6, 10) to generate the unqiue password for the user. but I have notice that sometimes( i got 5 out of 150 users) same password is generated and i use this as unqiueId for some purpose.

How reliable is this func开发者_开发百科tion?

I am not setting any other property like this 'numberOfNonAlphanumericCharacters'.

Any guidance will be of great help?

Thanks Harshit


it uses the RNGCryptoServiceProvider class to get a "random" sequence of bytes that are then used to generate the password. Something like the following

public static string GeneratePassword(int length, int numberOfNonAlphanumericCharacters)
{
    string str;
    int num;
    char[] punctuations= @"!@@$%^^*()_-+=[{]};:>|./?".ToCharArray();

    // removed checks for brevity //

    while(true)
    {
        byte[] data = new byte[length];
        char[] chArray = new char[length];
        int num2 = 0;
        new RNGCryptoServiceProvider().GetBytes(data);
        for (int i = 0; i < length; i++)
        {
            int num4 = data[i] % 0x57;
            if (num4 < 10)
            {
                // generate characters 0 -9
                chArray[i] = (char) (0x30 + num4);
            }
            else if (num4 < 0x24)
            {
                // generate characters A-Z
                chArray[i] = (char) ((0x41 + num4) - 10);
            }
            else if (num4 < 0x3e)
            {
                // generate characters a-z
                chArray[i] = (char) ((0x61 + num4) - 0x24);
            }
            else
            {
                // get a non alphanumeric character from the punctuations array
                chArray[i] = punctuations[num4 - 0x3e];
                num2++;
            }
        }
        if (num2 < numberOfNonAlphanumericCharacters)
        {
            Random random = new Random();
            for (int j = 0; j < (numberOfNonAlphanumericCharacters - num2); j++)
            {
                int num6;
                do
                {
                    num6 = random.Next(0, length);
                }
                while (!char.IsLetterOrDigit(chArray[num6]));
                chArray[num6] = punctuations[random.Next(0, punctuations.Length)];
            }
        }
        str = new string(chArray);
    }
    return str;
}


I took Russ Cam's answer but it got stuck in a never ending loop thanks to the while(true) statement that never breaks.

So here is my example which includes a Boolean (blnExactNumberOfNonAlphanumericCharacters) to specify whether the number of non alphanumeric characters should be exact (set to true), or minimum (set to false), which is how the original Membership.GeneratePassword method works:

public string GeneratePassword(int intLength, int intNumberOfNonAlphanumericCharacters, bool blnExactNumberOfNonAlphanumericCharacters)
{
    string strPassword = "";

    if (intLength > 0)
    {
        if ((intNumberOfNonAlphanumericCharacters >= 0) && (intNumberOfNonAlphanumericCharacters <= intLength))
        {
            char[] chrSpecialCharacters = @"!@$%^*()_-+=[{]};:>|.,/?".ToCharArray();
            byte[] data = new byte[intLength];
            char[] chrArray = new char[intLength];
            int intActualNumberOfSpecialCharacters = 0;
            new RNGCryptoServiceProvider().GetBytes(data);
            for (int i = 0; i < intLength; i++)
            {
                int intRemainderOfModuloDivision = data[i] % (62 + chrSpecialCharacters.Length); //was hex 0x57 (87)
                if (intRemainderOfModuloDivision < 10)
                {
                    // generate characters 0-9
                    chrArray[i] = (char)(48 + intRemainderOfModuloDivision); //was hex 0x30
                }
                else if (intRemainderOfModuloDivision < 36) //0x24
                {
                    // generate characters A-Z
                    chrArray[i] = (char)((65 + intRemainderOfModuloDivision) - 10); //was hex 0x41
                }
                else if (intRemainderOfModuloDivision < 62) //0x3e
                {
                    // generate characters a-z
                    chrArray[i] = (char)((97 + intRemainderOfModuloDivision) - 36); //was hex 0x61 & 0x24
                }
                else
                {
                    // get a non alphanumeric character from the special character array
                    chrArray[i] = chrSpecialCharacters[intRemainderOfModuloDivision - 62]; //was hex 0x3e
                    intActualNumberOfSpecialCharacters++;
                }
            }
            if (intActualNumberOfSpecialCharacters < intNumberOfNonAlphanumericCharacters)
            {
                //if there are less special characters than the minimum required amount then add the minimum required
                Random random = new Random();
                for (int j = 0; j < (intNumberOfNonAlphanumericCharacters - intActualNumberOfSpecialCharacters); j++)
                {
                    int intRandomArrayPointer;
                    do
                    {
                        intRandomArrayPointer = random.Next(0, intLength);
                    }
                    while (!char.IsLetterOrDigit(chrArray[intRandomArrayPointer]));
                    chrArray[intRandomArrayPointer] = chrSpecialCharacters[random.Next(0, chrSpecialCharacters.Length)];
                }
            }
            else if ((blnExactNumberOfNonAlphanumericCharacters) && (intActualNumberOfSpecialCharacters > intNumberOfNonAlphanumericCharacters))
            {
                //if the exact amount is needed then we replace unwanted ones with regular letters and/or digits
                Random random = new Random();
                for (int j = 0; j < (intActualNumberOfSpecialCharacters - intNumberOfNonAlphanumericCharacters); j++)
                {
                    int intRandomArrayPointer;
                    do
                    {
                        intRandomArrayPointer = random.Next(0, intLength);
                    }
                    while (char.IsLetterOrDigit(chrArray[intRandomArrayPointer]));

                    char[] chrLetterAndDigitArray = new char[62];

                    int intPointer = 0;

                    //add characters 0-9
                    for (int l = 48; l <= 57; l++)
                    {
                        chrLetterAndDigitArray[intPointer] = Convert.ToChar(l);
                        intPointer++;
                    }

                    //add characters A-Z
                    for (int l = 65; l <= 90; l++)
                    {
                        chrLetterAndDigitArray[intPointer] = Convert.ToChar(l);
                        intPointer++;
                    }

                    //add characters a-z
                    for (int l = 97; l <= 122; l++)
                    {
                        chrLetterAndDigitArray[intPointer] = Convert.ToChar(l);
                        intPointer++;
                    }
                    chrArray[intRandomArrayPointer] = chrLetterAndDigitArray[random.Next(0, chrLetterAndDigitArray.Length)]; 
                }                   
            }
            strPassword = new string(chrArray);
        }
    }
    return strPassword;
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜