10 * Copyright (c) 2015, Koynov Stas - skojnov@yandex.ru
12 * All rights reserved.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
17 * 1. Redistributions of source code must retain the above copyright notice, this
18 * list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials provided with the distribution.
24 * 3. Neither the name of the copyright holder nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 uCRC_t::uCRC_t(const std::string
&Name
, uint8_t Bits
, uint64_t Poly
, uint64_t Init
, bool RefIn
, bool RefOut
, uint64_t XorOut
) : name(Name
),
56 uCRC_t::uCRC_t(uint8_t Bits
, uint64_t Poly
, uint64_t Init
, bool RefIn
, bool RefOut
, uint64_t XorOut
) : poly(Poly
),
66 uint64_t uCRC_t::get_check() const
68 const uint8_t data
[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
70 return get_crc(data
, sizeof(data
));
73 int uCRC_t::set_bits(uint8_t new_value
)
75 if ((new_value
< 1) || (new_value
> 64))
84 uint64_t uCRC_t::get_crc(const void *data
, size_t len
) const
86 uint64_t crc
= get_raw_crc(data
, len
, crc_init
);
88 return get_final_crc(crc
);
91 int uCRC_t::get_crc(uint64_t &crc
, const char *file_name
) const
95 return get_crc(crc
, file_name
, buf
, sizeof(buf
));
98 int uCRC_t::get_crc(uint64_t &crc
, const char *file_name
, void *buf
, size_t size_buf
) const
100 std::ifstream
ifs(file_name
, std::ios_base::binary
);
102 if (!ifs
|| !buf
|| !size_buf
)
108 return get_crc(crc
, ifs
, buf
, size_buf
);
111 int uCRC_t::get_crc(uint64_t &crc
, std::ifstream
&ifs
, void *buf
, size_t size_buf
) const
117 ifs
.read(static_cast<char *>(buf
), size_buf
);
118 crc
= get_raw_crc(buf
, ifs
.gcount(), crc
);
121 crc
= get_final_crc(crc
);
123 return (ifs
.rdstate() & std::ios_base::badbit
); //return 0 if all good
126 uint64_t uCRC_t::get_raw_crc(const void *data
, size_t len
, uint64_t crc
) const
128 const uint8_t *buf
= static_cast<const uint8_t *>(data
);
134 crc
= (crc
>> 8) ^ crc_table
[(crc
^ *buf
++) & 0xff];
137 crc
= (crc
<< 8) ^ crc_table
[((crc
>> shift
) ^ *buf
++) & 0xff];
143 crc
= crc_table
[(crc
^ *buf
++) & 0xff];
146 crc
= crc_table
[((crc
<< shift
) ^ *buf
++) & 0xff];
152 uint64_t uCRC_t::get_final_crc(uint64_t raw_crc
) const
154 if (ref_out
^ ref_in
)
155 raw_crc
= reflect(raw_crc
, bits
);
158 raw_crc
&= crc_mask
; //for CRC not power 2
163 uint64_t uCRC_t::reflect(uint64_t data
, uint8_t num_bits
) const
165 uint64_t reflection
= 0;
169 reflection
= (reflection
<< 1) | (data
& 1);
176 void uCRC_t::init_crc_table()
178 //Calculation of the standard CRC table for byte.
179 for (int i
= 0; i
< 256; i
++)
184 for (uint8_t mask
= 0x80; mask
; mask
>>= 1)
199 crc
&= crc_mask
; //for CRC not power 2
202 crc_table
[reflect(i
, 8)] = reflect(crc
, bits
);
208 void uCRC_t::init_class()
210 top_bit
= (uint64_t)1 << (bits
- 1);
211 crc_mask
= ((top_bit
- 1) << 1) | 1;
219 crc_init
= reflect(init
, bits
);