-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathcrccalc.h
More file actions
87 lines (80 loc) · 1.74 KB
/
Copy pathcrccalc.h
File metadata and controls
87 lines (80 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#pragma once
#include <array>
#include <cstdint>
template<typename INT, INT poly, int nbits>
class CrcCalc {
std::array<INT, 256> table;
INT polymult(uint8_t b)
{
INT result = 0;
INT factor = poly;
for (int i = 0 ; i < 8 ; i++)
{
if (b & 0x80)
result ^= factor;
b <<= 1;
bool bit = factor&1;
factor >>= 1;
if (bit)
factor ^= poly;
}
return result;
}
void calc_table()
{
for (int i = 0 ; i < 256 ; i++)
table[i] = polymult(i);
}
public:
CrcCalc()
{
calc_table();
}
INT add(INT crc, uint8_t b) const
{
return table[(crc^b)&0xFF] ^ (crc>>8);
}
INT add(INT crc, const uint8_t *p, int size) const
{
while (size--)
crc = add(crc, *p++);
return crc;
}
INT calc(const uint8_t *p, int size) const
{
constexpr INT mask = ((((INT)1<<(nbits-1))-1)<<1) | 1;
return add(mask, p, size) ^ mask;
}
};
template<typename P>
uint16_t crc16(uint16_t crc, P ptr, size_t size)
{
static CrcCalc<uint16_t, 0x8408, 16> CRC;
return CRC.add(crc, ptr, size);
}
template<typename P>
uint16_t crc16(P ptr, size_t size)
{
return crc16(~0, ptr, size) ^ (~0);
}
template<typename V>
uint16_t crc16(const V& v)
{
return crc16(&v[0], v.size());
}
template<typename P>
uint32_t crc32(uint32_t crc, P ptr, size_t size)
{
static CrcCalc<uint32_t, 0xEDB88320, 32> CRC;
return CRC.add(crc, ptr, size);
}
template<typename P>
uint32_t crc32(P ptr, size_t size)
{
return crc32(~0, ptr, size) ^ (~0);
}
template<typename V>
uint32_t crc32(const V& v)
{
return crc32(&v[0], v.size());
}