old-nall/hash/crc16.hpp

66 lines
1.4 KiB
C++
Raw Permalink Normal View History

2016-05-15 10:42:10 +00:00
#pragma once
#include <nall/range.hpp>
2016-07-03 11:35:22 +00:00
#include <nall/string.hpp>
2016-05-15 10:42:10 +00:00
2016-07-03 11:35:22 +00:00
namespace nall { namespace Hash {
2016-05-15 10:42:10 +00:00
struct CRC16 {
CRC16() { reset(); }
2016-07-03 11:35:22 +00:00
CRC16(const void* values, uint size) : CRC16() { data(values, size); }
CRC16(const vector<uint8_t>& values) : CRC16() { data(values); }
CRC16(const string& values) : CRC16() { data(values); }
2016-05-15 10:42:10 +00:00
auto reset() -> void {
checksum = ~0;
}
auto data(uint8_t value) -> void {
2016-07-03 11:35:22 +00:00
checksum = (checksum >> 8) ^ table(checksum ^ value);
2016-05-15 10:42:10 +00:00
}
2016-07-03 11:35:22 +00:00
auto data(const void* values, uint size) -> void {
2016-05-15 10:42:10 +00:00
auto p = (const uint8_t*)values;
while(size--) data(*p++);
}
2016-07-03 11:35:22 +00:00
auto data(const vector<uint8_t>& values) -> void {
for(auto value : values) data(value);
}
auto data(const string& values) -> void {
for(auto value : values) data(value);
}
auto value() const -> uint16_t {
2016-05-15 10:42:10 +00:00
return ~checksum;
}
2016-07-03 11:35:22 +00:00
inline auto digest() const -> string {
return hex(value(), 4L);
}
2016-05-15 10:42:10 +00:00
private:
2016-07-03 11:35:22 +00:00
static auto table(uint8_t index) -> uint16_t {
static uint16_t table[256] = {0};
static bool initialized = false;
if(!initialized) {
initialized = true;
for(auto index : range(256)) {
uint16_t crc = index;
for(auto bit : range(8)) {
crc = (crc >> 1) ^ (crc & 1 ? 0x8408 : 0);
}
table[index] = crc;
}
}
return table[index];
}
2016-05-15 10:42:10 +00:00
uint16_t checksum;
};
}}