#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 */ 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; }