2017-04-30 45 views
-5

我想將一個正則表達式(對於密碼)轉換爲C++代碼。正則表達式到C++代碼

這是正則表達式:

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

的密碼應該至少有一個大寫字母,一個小寫字母,一個特殊字符和一個數字。然而,我的C++代碼似乎允許像「aaaaA1」這樣的密碼不包含特殊字符。我的代碼如下。

vector<string> StupidNonDynamicBrute(int Depth) { 
vector<string> Words; 
string Word = ""; 
regex Expression ("(?=^.{6,}$)(?=.*\\d)(?=.*[[email protected]#$%^&*(){}\\[\\]=\\+\\-_:;\"\'`<,>.?\\/|\\~]+)(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$"); 
ofstream Output; 
Output.open("Output1.txt"); 
char Letters[] ="[email protected]#$%^&*(){}[]=+-_:;\"\'`<,>.?/|\\~"; 
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中的所有可能的組合作爲密碼使用。我還創建了一個遞歸動態函數來執行此操作(對於任何密碼長度),但由於某種原因它速度非常慢。

+6

你爲什麼不只是檢查這些條件明確? (而不是試圖將它們全部塞進一個無法理解的正則表達式。) –

回答

1

這是更簡單做沒有正則表達式。只是檢查符合條件的字符:

static std::string specials = "[email protected]#$"; 
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; 
} 
+0

這種方式產生與以前完全相同的結果。它輸出的第一個字符串是aaaaA1,所以它認爲它找到了特殊字符。 –

+0

該錯誤似乎是它將所有字符標識爲特殊字符,並使用此特殊字符池: static string Specials =「!@#$%^&*(){} [] = + -_:; \」\ ''<,>。?/ | \\〜「; –

+0

@ΑριστείδηςΑγγελόπουλος - yup,代碼中的拼寫錯誤,我修正了它。std :: string :: find返回找到匹配的位置, std :: string :: npos)如果找不到匹配。 –

1

因爲你檢查很多組合這是非常緩慢的(即:6種可能性)...

只是檢查各條件:

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("[[email protected]#$%^&*(){}\[\]=\+\-_:;"'`<,>.?\/|\\~]"); 
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

我可能會做一些更直接:

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