-
Notifications
You must be signed in to change notification settings - Fork 13
/
crc.cc
145 lines (103 loc) · 3.58 KB
/
crc.cc
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <iostream>
#include <boost/dynamic_bitset.hpp>
#include "crc.hpp"
// Simple CRC class function definitions -----------------------------------//
my_crc_basic::my_crc_basic( unsigned int width,
my_crc_basic::value_type truncated_polynominal,
my_crc_basic::value_type initial_remainder, // = 0
my_crc_basic::value_type final_xor_value, // = 0
bool reflect_input, // = false
bool reflect_remainder // = false
)
: width_(width), rem_( initial_remainder ), poly_( truncated_polynominal )
, init_( initial_remainder ), final_( final_xor_value )
, rft_in_( reflect_input ), rft_out_( reflect_remainder )
{
high_bit_mask = 1ul << ( width - 1u );
sig_bits = (~( ~( 0ul ) << width )) ;
}
void my_crc_basic::set(my_crc_basic::value_type truncated_polynominal,
my_crc_basic::value_type initial_remainder, // = 0
my_crc_basic::value_type final_xor_value, // = 0
bool reflect_input, // = false
bool reflect_remainder // = false
) {
rem_ = initial_remainder;
poly_ = truncated_polynominal;
init_ = initial_remainder;
final_ = final_xor_value;
rft_in_ = reflect_input;
rft_out_ = reflect_remainder;
}
void my_crc_basic::reset(my_crc_basic::value_type new_rem) {
rem_ = new_rem;
}
void my_crc_basic::process_bit (bool bit) {
// compare the new bit with the remainder's highest
rem_ ^= ( bit ? high_bit_mask : 0u );
// a full polynominal division step is done when the highest bit is one
bool const do_poly_div = static_cast<bool>( rem_ & high_bit_mask );
// shift out the highest bit
rem_ <<= 1;
// carry out the division, if needed
if ( do_poly_div ) rem_ ^= poly_;
}
my_crc_basic::value_type my_crc_basic::checksum() const {
return ( (rft_out_ ? reflect( rem_ ) : rem_)
^ final_ ) & sig_bits;
}
void my_crc_basic::calc_crc(value_type const use_initial,
boost::dynamic_bitset<> const & msg) {
this->calc_crc(use_initial, msg, 0, AUTO);
}
bool my_crc_basic::calc_crc(value_type const use_initial,
boost::dynamic_bitset<> const& msg,
value_type const expected_crc,
FEED_TYPE feed_type) {
reset(use_initial);
if(feed_type == AUTO) {
if(rft_in_) {
if (msg.size() % 8 != 0) feed_type = LINEAR_REVERSED;
else feed_type = BYTEWISE_REVERSED;
}
else {
feed_type = LINEAR_FORWARD;
}
}
if(feed_type == LINEAR_FORWARD) {
for (size_t i = 0; i < msg.size(); i++) {
process_bit(msg[i]);
}
}
else if(feed_type == LINEAR_REVERSED) {
for (int i = msg.size()-1; i >= 0; i--) {
process_bit(msg[i]);
}
}
else if(feed_type == BYTEWISE_REVERSED) {
for(size_t i = 0; i < msg.size(); i+=8) {
// inverse feeding
for(int j = 1; j <= 8; j++)
process_bit(msg[i + 8 - j]);
}
}
return checksum() == expected_crc;
}
bool my_crc_basic::calc_crc(value_type const use_initial,
uint8_t msg[], size_t msg_length,
value_type const expected_crc) {
reset(use_initial);
//process_bytes(msg, msg_length);
return checksum() == expected_crc;
}
// Function that reflects its argument
my_crc_basic::value_type my_crc_basic::reflect(value_type x ) const {
value_type reflection = 0;
value_type const one = 1;
for( std::size_t i = 0 ; i < width_ ; ++i, x >>= 1 ) {
if ( x & one ) {
reflection |= ( one << (width_ - 1u - i) );
}
}
return reflection;
}