Грубая сила. Это Adler32, который я раньше не реализовывал и не беспокоил тестированием, так что вполне вероятно, что я все испортил. Я не ожидал бы, что исправленная версия будет работать значительно медленнее, если только я не сделал что-то колоссально неправильное.
Предполагается, что значение 32-битной контрольной суммы записывается в файл с прямым порядком байтов (я не нашел фиксированной точки с этим байтом с прямым порядком байтов):
#include <iostream>
#include <stdint.h>
#include <iomanip>
const int modulus = 65521;
void checkAllAdlers(uint32_t sofar, int depth, uint32_t a, uint32_t b) {
if (depth == 4) {
if ((b << 16) + a == sofar) {
std::cout << "Got a fixed point: 0x" <<
std::hex << std::setw(8) << std::setfill('0') <<
sofar << "\n";
}
return;
}
for (uint32_t i = 0; i < 256; ++i) {
uint32_t newa = a + i;
if (newa >= modulus) newa -= modulus;
uint32_t newb = b + a;
if (newb >= modulus) newb -= modulus;
checkAllAdlers(sofar + (i << (depth*8)), depth + 1, newa, newb);
}
return;
}
int main() {
checkAllAdlers(0, 0, 1, 0);
}
Выход:
$ g++ adler32fp.cpp -o adler32fp -O3 && time ./adler32fp
Got a fixed point: 0x03fb01fe
real 0m31.215s
user 0m30.326s
sys 0m0.015s
[Редактировать: несколько ошибок уже исправлено, я не уверен ни в какой корректности этого кода ;-) В любом случае, вы понимаете: 32-битная контрольная сумма, которая использует каждый байт ввода только один раз, очень дешева для грубой силы , Контрольные суммы обычно рассчитаны на быстрое вычисление, в то время как хэши обычно намного медленнее, даже несмотря на то, что они имеют поверхностно похожие эффекты. Если ваша контрольная сумма была «2 раунда Adler32» (это означает, что целевая контрольная сумма была результатом вычисления контрольной суммы, а затем вычисления контрольной суммы этой контрольной суммы), то мой рекурсивный подход не очень помог бы, было бы пропорционально меньше в общий между входами с общим префиксом. MD5 имеет 4 раунда, SHA-512 имеет 80.]