diff --git a/src/main.cpp b/src/main.cpp index e5fcd02..e6ea752 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,9 @@ #include "ec.h" #include "key_search.h" +// Command line options. +bool option_l33t = false; + #ifdef HAVE_THREADS #define n_thread_decl int n_threads = std::thread::hardware_concurrency() #define n_thread_argv \ @@ -56,10 +59,19 @@ void cmd_search(int argc, char **argv) { int n = 100; n_thread_decl; std::string search(argv[0]); - strlist_t words = strsplitwords(strtolower(search)); + strlist_t words; - // Strip words from non-base58. - base58_strip(words); + if (option_l33t) { + strlist_t tmp = strsplitwords(search); + for(int i = 0; i < tmp.size(); i++) { + strlist_t list = l33twords(base58_strip(tmp[i])); + words.reserve(words.size() + list.size()); + words.insert(words.end(), list.begin(), list.end()); + } + } else { + words = strsplitwords(strtolower(search)); + base58_strip(words); + } if (argc > 1) { n = atoi(argv[1]); @@ -71,7 +83,7 @@ void cmd_search(int argc, char **argv) { n_thread_argv; std::cout << "Searching for " << n - << " keys containing: " << search + << " keys containing: " << strjoin(words, ",") n_thread_outp << std::endl; @@ -108,6 +120,12 @@ int main(int argc, char **argv) { return 0; } + if (!strcmp(argv[1], "--l33t")) { + option_l33t = true; + argc--; + argv = &argv[1]; + } + if (!strcmp(argv[1], "search")) { if (argc < 3) { std::cout << "You must specify a word list." << std::endl; diff --git a/src/string.cpp b/src/string.cpp index 91b0960..a90388b 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -46,6 +46,21 @@ strlist_t strsplit(const std::string& str, const std::string& delim) { return r; } +std::string strjoin(const strlist_t& list, const std::string& delim) { + + std::string out; + + for(const std::string& item : list) { + out += item + delim; + } + + if (out.length() > 0) { + out.erase(out.end() - delim.length()); + } + + return out; +} + std::string& strtolower(std::string& str) { std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::tolower(c); }); return str; @@ -84,3 +99,52 @@ strlist_t& base58_strip(strlist_t& list) { std::transform(list.begin(), list.end(), list.begin(), [](std::string& str){ return base58_strip(str); }); return list; } + +static bool is_l33t(char ch, char& r) { + + // '1', '2', '3', '4', '5', '6', '7', '8', '9' + static char alphabet[9] = { 'l', 'z', 'e', 'a', 's', 'G', 't', 'B', 'g' }; + + for(int i = 0; i < sizeof(alphabet) / sizeof(char); i++) { + + if (ch == alphabet[i]) { + r = '1' + i; + return true; + } + } + return false; +} + +static void _l33t(strlist_t& list, const std::string& a, int pos) { + + // Find the next character to be replaced. + for(int i = pos; i < a.length(); i++) { + + char ch; + if (is_l33t(a[i], ch)) { + // create a new string and replace the character. + std::string b = a; + b[i] = ch; + + // Store the new string as the result. + list.push_back(b); + + // Perform the same algorithm for both strings + // at the next position. + _l33t(list, a, i + 1); + _l33t(list, b, i + 1); + break; + } + } +} + +strlist_t l33twords(const std::string& str) { + + strlist_t list; + + // Store the original string as the first in list. + list.push_back(str); + + _l33t(list, str, 0); + return list; +} diff --git a/src/string.h b/src/string.h index e364fed..d006579 100644 --- a/src/string.h +++ b/src/string.h @@ -33,6 +33,8 @@ strlist_t strsplitwords(const std::string& str, const std::string& delim = ","); strlist_t strsplit(const std::string& str, const std::string& delim); +std::string strjoin(const strlist_t& list, const std::string& delim); + std::string& strtolower(std::string& str); std::string& rtrim(std::string& str); @@ -42,4 +44,6 @@ std::string& trim(std::string& str); std::string& base58_strip(std::string &str); strlist_t& base58_strip(strlist_t& list); +strlist_t l33twords(const std::string& str); + #endif /* STRING_H */