Advertisement
gridem

synca: md5 bruteforce with portals, workers and channels

Apr 15th, 2015
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.07 KB | None | 0 0
  1. #include <synca/synca.h>
  2. #include <synca/log.h>
  3.  
  4. #include <fstream>
  5. #include <regex>
  6. #include <synca/channel.h>
  7.  
  8. #include "md5.h"
  9.  
  10. using namespace synca;
  11.  
  12. void next(char& b)
  13. {
  14.     switch (b)
  15.     {
  16.     case 'z': b = '0'; break;
  17.     case '9': b = 'a'; break;
  18.     default: ++ b; break;
  19.     }
  20. }
  21.  
  22. bool next(std::string& p)
  23. {
  24.     for (auto e = p.rbegin(); e != p.rend(); ++ e)
  25.     {
  26.         next(*e);
  27.         if (*e != '0')
  28.             return true;
  29.     }
  30.     return false;
  31. }
  32.  
  33. std::vector<std::string> splitLine(const std::string& line)
  34. {
  35.     static const std::regex fmt(R"(^\s*([0-9a-fA-F]+)\s+([0-9a-z]+)\s+([0-9a-z]+)\s*$)");
  36.     std::smatch parts;
  37.     VERIFY(std::regex_match(line, parts, fmt), "Invalid format");
  38.     return {parts.str(1), parts.str(2), parts.str(3)};
  39. }
  40.  
  41. struct Disk
  42. {
  43.     boost::optional<std::string> readLine(std::istream& is)
  44.     {
  45.         std::string line;
  46.         return std::getline(is, line) ? boost::optional<std::string>{line} : boost::optional<std::string>{};
  47.     }
  48. };
  49.  
  50. struct Master
  51. {
  52.     void processFile(const char* name)
  53.     {
  54.         JLOG("opening: " << name);
  55.         std::ifstream ifs(name);
  56.         VERIFY(ifs, "File open error");
  57.         while (true)
  58.         {
  59.             auto line = portal<Disk>()->readLine(ifs);
  60.             if (!line)
  61.                 break;
  62.             if (line->empty())
  63.                 continue;
  64.             lines.put(*line);
  65.             tryStartWorker();
  66.         }
  67.         isClosed = true;
  68.         lines.close();
  69.         LOG("file parsed");
  70.     }
  71.  
  72. private:
  73.     void onPassword(const std::string& md5, const std::string& pwd)
  74.     {
  75.         RJLOG(md5 << ", found password: " << pwd);
  76.     }
  77.  
  78.     void onError(const std::string& line, const std::string& e)
  79.     {
  80.         RJLOG(line << ", error: " << e);
  81.     }
  82.  
  83.     void onNotFound(const std::string& md5)
  84.     {
  85.         RJLOG(md5 << ", not found");
  86.     }
  87.  
  88.     void onWorkerCompleted()
  89.     {
  90.         ++ availableWorkers;
  91.         tryStartWorker();
  92.     }
  93.  
  94.     static void processLine(const std::string& line)
  95.     {
  96.         JLOG("process line: " << line);
  97.         auto split = splitLine(line);
  98.         auto&& md5hex = split[0];
  99.         auto&& left = split[1];
  100.         auto&& right = split[2];
  101.         JLOG("process: " << md5hex << "," << left << "," << right);
  102.         VERIFY(left.size() == right.size() && left <= right, "Inconsistent range");
  103.         auto etalon = md5_cpp11::from_hex_string(md5hex);
  104.         while (true)
  105.         {
  106.             if (md5_cpp11::make_digest(left) == etalon)
  107.             {
  108.                 portal<Master>()->onPassword(md5hex, left);
  109.                 return;
  110.             }
  111.             if (!next(left) || left == right)
  112.             {
  113.                 portal<Master>()->onNotFound(md5hex);
  114.                 return;
  115.             }
  116.         }
  117.     }
  118.  
  119.     static void worker(Channel<std::string>& lines)
  120.     {
  121.         std::string line;
  122.         try
  123.         {
  124.             while (lines.get(line))
  125.                 processLine(line);
  126.         }
  127.         catch (std::exception& e)
  128.         {
  129.             portal<Master>()->onError(line, e.what());
  130.         }
  131.         portal<Master>()->onWorkerCompleted();
  132.     }
  133.  
  134.     void tryStartWorker()
  135.     {
  136.         if (isClosed || availableWorkers == 0)
  137.             return;
  138.         -- availableWorkers;
  139.         go([&] {
  140.             worker(lines);
  141.         });
  142.     }
  143.  
  144.     int availableWorkers = threadConcurrency();
  145.     bool isClosed = false;
  146.     Channel<std::string> lines;
  147. };
  148.  
  149. int main(int argv, const char* argc[])
  150. {
  151.     try
  152.     {
  153.         VERIFY(argv == 2, "Invalid args");
  154.         ThreadPool cpu(threadConcurrency(), "cpu");
  155.         ThreadPool disk(1, "disk");
  156.         scheduler<DefaultTag>().attach(cpu);
  157.         Alone masterAlone(cpu, "master");
  158.         portal<Master>().attach(masterAlone);
  159.         portal<Disk>().attach(disk);
  160.         go([&] {
  161.             portal<Master>()->processFile(argc[1]);
  162.         });
  163.         waitForAll();
  164.     }
  165.     catch (std::exception& e)
  166.     {
  167.         RLOG("Error: " << e.what());
  168.         return 1;
  169.     }
  170.     return 0;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement