# Сначала нужно сохранить данные о коммите в файл:
# (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) >> file.txt
#
# Дальше нужно указать с какого байта начинаем декрементить счетчик.
# Пока что это место нахожу с момощью ручек в дебаг режиме.
#include <iostream>
#include <fstream>
#include <cassert>
#include <vector>
#include <openssl/sha.h>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <chrono>
std::vector<unsigned char> read(const std::string & path) {
std::ifstream input(path, std::ios::binary);
assert(input.is_open());
std::vector<unsigned char> result;
while (!input.eof())
{
const auto ch = input.get();
result.push_back(ch);
}
assert(result.size() > 1);
result.pop_back();
return result;
}
template <class ContainerT>
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 <class ContainerT>
void decrease(ContainerT & buffer, size_t position) {
buffer[position] -= 1;
update(buffer, position);
}
template <class ContainerT>
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 <class ContainerT>
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<unsigned char>;
ContainerT target = from_string<ContainerT>("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<double>(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<std::chrono::seconds>(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<double>(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<std::chrono::seconds>(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;
}
Comments
0 B
|👍
/👎