mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
98 lines
No EOL
3.1 KiB
C++
98 lines
No EOL
3.1 KiB
C++
#include "crc_generic.h"
|
|
|
|
namespace codings
|
|
{
|
|
namespace crc
|
|
{
|
|
GenericCRC::GenericCRC(unsigned num_bits,
|
|
uint64_t poly,
|
|
uint64_t initial_value,
|
|
uint64_t final_xor,
|
|
bool input_reflected,
|
|
bool result_reflected)
|
|
: d_num_bits(num_bits),
|
|
d_mask(num_bits == 64 ? ~static_cast<uint64_t>(0)
|
|
: (static_cast<uint64_t>(1) << num_bits) - 1),
|
|
d_initial_value(initial_value & d_mask),
|
|
d_final_xor(final_xor & d_mask),
|
|
d_input_reflected(input_reflected),
|
|
d_result_reflected(result_reflected)
|
|
{
|
|
d_table[0] = 0;
|
|
if (d_input_reflected)
|
|
{
|
|
poly = reflect(poly);
|
|
uint64_t crc = 1;
|
|
int i = 128;
|
|
do
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc >>= 1;
|
|
for (int j = 0; j < 256; j += 2 * i)
|
|
d_table[i + j] = (crc ^ d_table[j]) & d_mask;
|
|
i >>= 1;
|
|
} while (i > 0);
|
|
}
|
|
else
|
|
{
|
|
const uint64_t msb = static_cast<uint64_t>(1) << (num_bits - 1);
|
|
uint64_t crc = msb;
|
|
int i = 1;
|
|
do
|
|
{
|
|
if (crc & msb)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc <<= 1;
|
|
for (int j = 0; j < i; ++j)
|
|
d_table[i + j] = (crc ^ d_table[j]) & d_mask;
|
|
i <<= 1;
|
|
} while (i < 256);
|
|
}
|
|
}
|
|
|
|
uint64_t GenericCRC::compute(uint8_t *data, unsigned int len)
|
|
{
|
|
uint64_t rem = d_initial_value;
|
|
|
|
if (d_input_reflected)
|
|
{
|
|
for (unsigned int i = 0; i < len; ++i)
|
|
{
|
|
uint8_t byte = data[i];
|
|
uint8_t idx = (rem ^ byte) & 0xff;
|
|
rem = d_table[idx] ^ (rem >> 8);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (unsigned int i = 0; i < len; ++i)
|
|
{
|
|
uint8_t byte = data[i];
|
|
uint8_t idx = ((rem >> (d_num_bits - 8)) ^ byte) & 0xff;
|
|
rem = (d_table[idx] ^ (rem << 8)) & d_mask;
|
|
}
|
|
}
|
|
|
|
if (d_input_reflected != d_result_reflected)
|
|
rem = reflect(rem);
|
|
|
|
rem = rem ^ d_final_xor;
|
|
return rem;
|
|
}
|
|
|
|
uint64_t GenericCRC::reflect(uint64_t word) const
|
|
{
|
|
uint64_t ret;
|
|
ret = word & 1;
|
|
for (unsigned i = 1; i < d_num_bits; ++i)
|
|
{
|
|
word >>= 1;
|
|
ret = (ret << 1) | (word & 1);
|
|
}
|
|
return ret;
|
|
}
|
|
}
|
|
} |