Advertisement
Gistrec

Git hash generator

Apr 22nd, 2021 (edited)
718
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.65 KB | None | 0 0
  1. # Сначала нужно сохранить данные о коммите в файл:
  2. # (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) >> file.txt
  3. #
  4. # Дальше нужно указать с какого байта начинаем декрементить счетчик.
  5. # Пока что это место нахожу с момощью ручек в дебаг режиме.
  6. #include <iostream>
  7. #include <fstream>
  8. #include <cassert>
  9. #include <vector>
  10.  
  11. #include <openssl/sha.h>
  12. #include <iomanip>
  13. #include <algorithm>
  14. #include <cmath>
  15.  
  16. #include <chrono>
  17.  
  18.  
  19. std::vector<unsigned char> read(const std::string & path) {
  20.     std::ifstream input(path, std::ios::binary);
  21.     assert(input.is_open());
  22.  
  23.     std::vector<unsigned char> result;
  24.     while (!input.eof())
  25.     {
  26.         const auto ch = input.get();
  27.         result.push_back(ch);
  28.     }
  29.     assert(result.size() > 1);
  30.     result.pop_back();
  31.  
  32.     return result;
  33. }
  34.  
  35. template <class ContainerT>
  36. void update(ContainerT & buffer, size_t position) {
  37.     if (buffer[position] < u'0')
  38.     {
  39.         buffer[position] = u'9';
  40.         // Уменьшаем предыдищуй разряд и обновляем его
  41.         buffer[position - 1] -= 1;
  42.         update(buffer, position - 1);
  43.     }
  44. }
  45.  
  46. template <class ContainerT>
  47. void decrease(ContainerT & buffer, size_t position) {
  48.     buffer[position] -= 1;
  49.     update(buffer, position);
  50. }
  51.  
  52. template <class ContainerT>
  53. std::string to_string(const ContainerT & buffer) {
  54.     std::stringstream result;
  55.     result << std::hex << std::setfill('0');
  56.     for (const auto byte : buffer)
  57.     {
  58.         result << std::setw(2) << (int)byte;
  59.     }
  60.     return result.str();
  61. }
  62.  
  63. template <class ContainerT>
  64. ContainerT from_string(const std::string & string) {
  65.     ContainerT result;
  66.     for (auto i = 0U; i < string.size(); i += 2) {
  67.         //! Note: С unsigned char не работает.
  68.         unsigned int buffer;
  69.  
  70.         std::istringstream iss(string.substr(i, 2));
  71.         iss >> std::hex >> buffer;
  72.  
  73.         result.push_back(buffer);
  74.     }
  75.     return result;
  76. }
  77.  
  78. int main() {
  79.     using ContainerT = std::vector<unsigned char>;
  80.     ContainerT target = from_string<ContainerT>("aaaaaa");
  81.     ContainerT buffer = read("/home/alex/CLionProjects/git-hash/file.txt");
  82.     ContainerT result(SHA_DIGEST_LENGTH);
  83.  
  84.     size_t iterations = 0;
  85.  
  86.     const auto time_start = std::chrono::high_resolution_clock::now();
  87.  
  88.     while (!std::equal(target.begin(), target.end(), result.begin())) {
  89.         iterations++;
  90.  
  91.         decrease(buffer, 99);
  92.  
  93.         SHA1(buffer.data(), buffer.size(), result.data());
  94.  
  95.         if (iterations % (2 << 17) == 0)
  96.         {
  97.             const auto ratio = static_cast<double>(iterations) / std::pow(16, target.size() * 2);
  98.  
  99.             const auto time_now = std::chrono::high_resolution_clock::now();
  100.             const auto elapsed_in_sec = std::chrono::duration_cast<std::chrono::seconds>(time_now - time_start).count();
  101.  
  102.             const auto estimated = elapsed_in_sec / ratio;
  103.  
  104.             std::cout << std::dec << "[" << iterations << "] Compute " << round(ratio * 10000) / 100 << "%, ";
  105.             std::cout << "Elapsed " << elapsed_in_sec << " sec, Estimated " << std::round(estimated) << " sec." << std::endl;
  106.         }
  107.     }
  108.     const auto ratio = static_cast<double>(iterations) / std::pow(16, target.size() * 2);
  109.  
  110.     const auto time_now = std::chrono::high_resolution_clock::now();
  111.     const auto elapsed_in_sec = std::chrono::duration_cast<std::chrono::seconds>(time_now - time_start).count();
  112.  
  113.     std::cout << std::dec << "[" << iterations << "] Compute " << ratio * 100 << "%, ";
  114.     std::cout << "Elapsed " << elapsed_in_sec << " sec." << std::endl;
  115.     std::cout << "Result hash: " << to_string(result) << std::endl;
  116.  
  117.     for (const auto symbol : buffer) {
  118.         std::cout << symbol;
  119.     }
  120.     std::cout << std::endl;
  121.  
  122.     return 0;
  123. }
  124.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement