正则表达式到C ++代码

时间:2017-04-30 16:23:28

标签: c++ regex

我正在尝试将正则表达式(用于密码)转换为c ++代码。

这是正则表达式:

(?=^.{6,}$)(?=.*\d)(?=.*[!@#$%^&*(){}\[\]=\+\-_:;"'`<,>.?\/|\\~]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$

密码应至少包含一个大写字母,一个小写字母,一个特殊字符和一个数字。然而,我的c ++代码似乎允许像“aaaaA1”这样的密码不包含特殊字符。我的代码如下。

vector<string> StupidNonDynamicBrute(int Depth) {
vector<string> Words;
string Word = "";
regex Expression ("(?=^.{6,}$)(?=.*\\d)(?=.*[!@#$%^&*(){}\\[\\]=\\+\\-_:;\"\'`<,>.?\\/|\\~]+)(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$");
ofstream Output;
Output.open("Output1.txt");
char Letters[] ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}[]=+-_:;\"\'`<,>.?/|\\~";
for (int i = 0; i < 94; i++) {
    for (int j = 0; j < 94; j++) {
        for (int k = 0; k < 94; k++) {
            for (int b = 0; b < 94; b++) {
                if (Depth > 4) {
                    for (int m = 0; m < 94; m++) {
                        for (int v = 0; v < 94; v++) {
                            Word = "";
                            Word += Letters[i];
                            Word += Letters[j];
                            Word += Letters[k];
                            Word += Letters[b];
                            Word += Letters[m];
                            Word += Letters[v];
                            if (regex_match(Word, Expression)) {
                                Words.push_back(Word);
                                Output << Word << endl;
                            }
                        }
                    }
                } else {
                    Word = "";
                    Word += Letters[i];
                    Word += Letters[j];
                    Word += Letters[k];
                    Word += Letters[b];
                    Words.push_back(Word);
                    Output << Word << endl;
                }
            }
        }
    }
}
return Words;
}

对代码的一些见解:它生成字母,数字和符号的所有可能组合,长度为4或6,以用作密码。我还创建了一个递归动态函数来执行此操作(对于任何密码长度)但由于某种原因它非常慢。

3 个答案:

答案 0 :(得分:1)

这是非常慢的,因为你检查很多组合(即:6 94 的可能性)......

只需检查每个条件:

for(int i = 0; i < input.length(); i++)
{
    char c = input[i];
    if(isupper(c))
        containsUpper = true;
    if(islower(c))
        containsLower = true;
}

if (std::find_if(input.begin(), input.end(), (int(*)(int))std::isdigit) != input.end())
{
    containsDigit = true;
}

boost::regex re("[!@#$%^&*(){}\[\]=\+\-_:;"'`<,>.?\/|\\~]");
boost::match_results<std::string::const_iterator> what;
bool containsSpecials = boost::regex_search(input.begin(), input.end(), what, re, boost::match_default);

bool isPasswordValid = containsSpecials && containsLower && containsUpper && containsDigit;

答案 1 :(得分:1)

没有正则表达式,这样做要简单得多。只需检查符合条件的字符:

static std::string specials = "!@#$";
bool validate(std::string str) {
    bool has_lowercase = false;
    bool has_uppercase = false;
    bool has_digit = false;
    bool has_special = false;
    std::string::size_type pos = 0;
    while (pos < str.size()
        && !has_lowercase && !has_uppercase
        && !has_digit && !has_special) {
        if (is_lower(str[pos])
            has_lowercase = true;
        if (is_upper(str[pos])
            has_uppercase = true;
        if (is_digit(str[pos])
            has_digit = true;
        if (specials.find(str[pos]) != std::string::npos)
            has_special = true;
        ++pos;
    }
    return has_lowercase && has_uppercase && has_digit && has_special;
}

答案 2 :(得分:1)

我可能会做更直接的事情:

bool is_valid_password(std::string const& s)
{
    if(s.size() < 6)
        return false;

    // one uppercase
    if(std::find_if(std::begin(s), std::end(s),
        [](char c){ return std::isupper(c); }) == std::end(s))
            return false;

    // one lowercase
    if(std::find_if(std::begin(s), std::end(s),
        [](char c){ return std::islower(c); }) == std::end(s))
            return false;

    // one special
    if(std::find_if(std::begin(s), std::end(s),
        [](char c){ return std::ispunct(c); }) == std::end(s))
            return false;

    // one number
    if(std::find_if(std::begin(s), std::end(s),
        [](char c){ return std::isdigit(c); }) == std::end(s))
            return false;

    return true;
}