Calculating percent chance

时间:2015-09-29 00:49:07

标签: c++ random logic percentage

So my objective is to create a random password generator of length n (n >= 5 && n <= 15) that adds in only two numbers at random locations.

(e.g. 7S4js 86dJxD h6Zqs9K)

I have this working... or so I want to believe. What I want to know is will my code ALWAYS work at determining whether or not a number should be inserted.

'newPassword': Returns a string of length 'len', using 'nums' numbers.

std::string newPassword(int len, int nums)
{
    std::string password = "";

    // Required numbers
    int req = nums;

    for (int i = 0; i < len; i++)
    {
        bool needNum = req > 0;

        bool chance = rand() % len > req;

        bool useNum = needNum && chance;

        if (useNum)
            req--;

        char c = nextChar(useNum);

        password += c;
    }

    return password;
}

'nextChar': Returns a random character. The character will be a number if 'isNum' is true.

char nextChar(bool isNum)
{
    char c;

    if (!isNum)
    {
        // 50% chance to decide upper or lower case
        if (rand() % 100 < 50)
        {
            c = 'a' + rand() % 26;
        }
        else
        {
            c = 'A' + rand() % 26;
        }
    }
    else
    {
        // Random number 0-9
        c = '0' + rand() % 10;
    }

    return c;
}

So specifically, will the 'chance' variable in 'newPassword' work all the time?

1 个答案:

答案 0 :(得分:0)

rand()是生成随机数的过时而可怕的方法。 c ++ 11 <random>标题为处理各种随机内容提供了更高质量的工具。

您选择字母或数字的方式并不总是有效。我会以不同的方式处理它:生成所需数量的字母和数字然后随机播放字符串。它可能不是最有效的方式,但鉴于您对密码长度的要求,我更重视代码清晰度。

#include <string>
#include <random>
#include <algorithm>

std::string generatePassword(int length, int nDigits)
{
    std::string password;
    password.resize(length);

    std::mt19937 generator{std::random_device{}()};

    // Generate capital/lowercase letters
    std::uniform_int_distribution<char> letterGen(0, 2 * 26 - 1);
    auto digitsBeginIter = std::generate_n(password.begin(), length - nDigits, 
                  [&letterGen, &generator]() { 
                      auto l = letterGen(generator); 
                      return l < 26 ? 'a' + l : 'A' + (l - 26); 
                  });

    // Generate the digits
    std::uniform_int_distribution<char> digitGen('0', '9');
    std::generate_n(digitsBeginIter, nDigits, 
                    [&digitGen, &generator]() { return digitGen(generator); });

    // Shuffle the string
    std::shuffle(password.begin(), password.end(), generator);

    return password;
}