.net中的BasePage.GeneratePassword如何工作?

时间:2009-11-10 00:36:38

标签: .net

我正在使用BasePage.GeneratePassword(6,10)为用户生成unqiue密码。 但我注意到有时(我有150个用户中的5个)生成了相同的密码,我出于某种目的将其用作unqiueId。

这个功能有多可靠?

我没有设置任何其他属性,例如'numberOfNonAlphanumericCharacters'。

任何指导都会有很大的帮助吗?

由于 Harshit

2 个答案:

答案 0 :(得分:1)

它使用RNGCryptoServiceProvider类来获取“随机”字节序列,然后用于生成密码。类似于以下内容

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

答案 1 :(得分:0)

我接受了Russ Cam的回答,但由于永远不会破坏的while(true)语句,它被困在一个永无止境的循环中。

所以这是我的示例,其中包含一个布尔值(blnExactNumberOfNonAlphanumericCharacters),用于指定非字母数字字符的数量是否应该精确(设置为true)或最小值(设置为false),这是原始Membership.GeneratePassword方法的方式工作原理:

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