74 lines
2.1 KiB
C++
74 lines
2.1 KiB
C++
#include "Rabin_fingerprint.hpp"
|
|
|
|
Rabin_fingerprint::Rabin_fingerprint(uint32_t p, size_t window_size_in_bits) {
|
|
set_modulo_polynomial(p);
|
|
set_shift_polynomial(window_size_in_bits);
|
|
}
|
|
|
|
void Rabin_fingerprint::set_modulo_polynomial (uint32_t p) {
|
|
polynomial = p & ((uint32_t)pow(2, 31)-1);
|
|
}
|
|
|
|
void Rabin_fingerprint::set_shift_polynomial (size_t window_size_in_bits) {
|
|
#ifndef NDEBUG
|
|
if (polynomial == 0)
|
|
throw std::logic_error("Call set_modulo_polynomial first, as this function depends on the polynomial variable being set.");
|
|
#endif
|
|
|
|
shift_polynomial = 1;
|
|
|
|
// NOTE: We shift the bit 1 space too long, since we are removing the bit that has been pushed outside the window
|
|
for (size_t i = 0; i < window_size_in_bits; i++) {
|
|
shift_polynomial <<= 1;
|
|
if ((shift_polynomial & (uint32_t)pow(2, 31)) != 0)
|
|
shift_polynomial ^= polynomial;
|
|
}
|
|
}
|
|
|
|
|
|
void Rabin_fingerprint::push_char (char c) {
|
|
std::bitset<8> b(c);
|
|
for (char i = 7; i >= 0; i--) {
|
|
push_bit((bool)b[i]);
|
|
}
|
|
}
|
|
|
|
void Rabin_fingerprint::push_bit (bool b) {
|
|
fingerprint <<= 1;
|
|
fingerprint |= b;
|
|
if ((fingerprint & (uint32_t)pow(2, 31)) != 0)
|
|
fingerprint ^= polynomial;
|
|
}
|
|
|
|
void Rabin_fingerprint::shift_bit (bool b) {
|
|
#ifndef NDEBUG
|
|
if (shift_polynomial == 0)
|
|
throw std::logic_error("Call set_shift_polynomial first, as this function depends on the shift_polynomial variable being set.");
|
|
#endif
|
|
|
|
if (b)
|
|
fingerprint ^= shift_polynomial;
|
|
}
|
|
|
|
void Rabin_fingerprint::slide_char (char c_in, char c_out) {
|
|
std::bitset<8> b_in(c_in);
|
|
std::bitset<8> b_out(c_out);
|
|
for (char i = 7; i >= 0; i--) {
|
|
slide_bit((bool)b_in[i], (bool)b_out[i]);
|
|
}
|
|
}
|
|
|
|
/* #include <iostream> */
|
|
void Rabin_fingerprint::slide_bit (bool b_in, bool b_out) {
|
|
/* std::cout << "bitset b(c): " << b << std::endl; */
|
|
/* std::cout << "push bit " << b[i] << std::endl; */
|
|
/* std::cout << "push bit " << b_in << std::endl; */
|
|
push_bit(b_in);
|
|
/* std::cout << "shift bit " << b_out << std::endl; */
|
|
shift_bit(b_out);
|
|
}
|
|
|
|
uint32_t Rabin_fingerprint::get_fingerprint () {
|
|
return fingerprint;
|
|
}
|