# Сначала нужно сохранить данные о коммите в файл: # (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) >> file.txt # # Дальше нужно указать с какого байта начинаем декрементить счетчик. # Пока что это место нахожу с момощью ручек в дебаг режиме. #include #include #include #include #include #include #include #include #include std::vector read(const std::string & path) { std::ifstream input(path, std::ios::binary); assert(input.is_open()); std::vector result; while (!input.eof()) { const auto ch = input.get(); result.push_back(ch); } assert(result.size() > 1); result.pop_back(); return result; } template void update(ContainerT & buffer, size_t position) { if (buffer[position] < u'0') { buffer[position] = u'9'; // Уменьшаем предыдищуй разряд и обновляем его buffer[position - 1] -= 1; update(buffer, position - 1); } } template void decrease(ContainerT & buffer, size_t position) { buffer[position] -= 1; update(buffer, position); } template std::string to_string(const ContainerT & buffer) { std::stringstream result; result << std::hex << std::setfill('0'); for (const auto byte : buffer) { result << std::setw(2) << (int)byte; } return result.str(); } template ContainerT from_string(const std::string & string) { ContainerT result; for (auto i = 0U; i < string.size(); i += 2) { //! Note: С unsigned char не работает. unsigned int buffer; std::istringstream iss(string.substr(i, 2)); iss >> std::hex >> buffer; result.push_back(buffer); } return result; } int main() { using ContainerT = std::vector; ContainerT target = from_string("aaaaaa"); ContainerT buffer = read("/home/alex/CLionProjects/git-hash/file.txt"); ContainerT result(SHA_DIGEST_LENGTH); size_t iterations = 0; const auto time_start = std::chrono::high_resolution_clock::now(); while (!std::equal(target.begin(), target.end(), result.begin())) { iterations++; decrease(buffer, 99); SHA1(buffer.data(), buffer.size(), result.data()); if (iterations % (2 << 17) == 0) { const auto ratio = static_cast(iterations) / std::pow(16, target.size() * 2); const auto time_now = std::chrono::high_resolution_clock::now(); const auto elapsed_in_sec = std::chrono::duration_cast(time_now - time_start).count(); const auto estimated = elapsed_in_sec / ratio; std::cout << std::dec << "[" << iterations << "] Compute " << round(ratio * 10000) / 100 << "%, "; std::cout << "Elapsed " << elapsed_in_sec << " sec, Estimated " << std::round(estimated) << " sec." << std::endl; } } const auto ratio = static_cast(iterations) / std::pow(16, target.size() * 2); const auto time_now = std::chrono::high_resolution_clock::now(); const auto elapsed_in_sec = std::chrono::duration_cast(time_now - time_start).count(); std::cout << std::dec << "[" << iterations << "] Compute " << ratio * 100 << "%, "; std::cout << "Elapsed " << elapsed_in_sec << " sec." << std::endl; std::cout << "Result hash: " << to_string(result) << std::endl; for (const auto symbol : buffer) { std::cout << symbol; } std::cout << std::endl; return 0; }