mirror of
https://github.com/aicodix/dsp.git
synced 2026-04-27 14:30:36 +00:00
need CRCs way to often
This commit is contained in:
parent
6120bb163f
commit
5eec31a61f
2 changed files with 93 additions and 0 deletions
16
README.md
16
README.md
|
|
@ -38,3 +38,19 @@ Read and write [WAV](https://en.wikipedia.org/wiki/WAV) files
|
|||
Algorithm for computing uniform and [natural cubic splines](https://en.wikipedia.org/wiki/Spline_(mathematics)#Algorithm_for_computing_natural_cubic_splines)
|
||||
Very useful for data interpolation.
|
||||
|
||||
### [crc.hh](crc.hh)
|
||||
|
||||
A [Cyclic redundancy check](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) may not really be DSP-related, but it is needed over and over again when you do DSP that it fits just perfectly here.
|
||||
|
||||
For example, if we need to integrate CRC32 checking for a few bytes, like in the following:
|
||||
```
|
||||
# echo -n 'Hello World!' | rhash -C -
|
||||
(stdin) 1C291CA3
|
||||
```
|
||||
We can add it to our project as simple as that:
|
||||
```
|
||||
DSP::CRC<uint32_t> crc(0xEDB88320, 0xFFFFFFFF);
|
||||
for (uint8_t c: std::string("Hello World!")) crc(c);
|
||||
assert(!crc(uint32_t(~0x1C291CA3)));
|
||||
```
|
||||
|
||||
|
|
|
|||
77
crc.hh
Normal file
77
crc.hh
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Cyclic redundancy check
|
||||
|
||||
Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#ifndef CRC_HH
|
||||
#define CRC_HH
|
||||
|
||||
namespace DSP {
|
||||
|
||||
template <typename TYPE>
|
||||
class CRC
|
||||
{
|
||||
static const int BYTES = sizeof(TYPE);
|
||||
TYPE lut[BYTES * 256];
|
||||
TYPE poly;
|
||||
TYPE crc;
|
||||
public:
|
||||
CRC(TYPE poly, TYPE crc = 0) : poly(poly), crc(crc)
|
||||
{
|
||||
// exploit linearity of CRC only bytewise
|
||||
for (int k = 0; k < BYTES; ++k) {
|
||||
for (int j = 0; j < 256; ++j) {
|
||||
TYPE tmp = j << (k << 3);
|
||||
for (int i = 8; i; --i)
|
||||
tmp = (tmp >> 1) ^ ((tmp & 1) * poly);
|
||||
lut[(k << 8) + j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
void reset(TYPE v)
|
||||
{
|
||||
crc = v;
|
||||
}
|
||||
TYPE operator()(bool data)
|
||||
{
|
||||
TYPE tmp = crc ^ data;
|
||||
tmp = (tmp >> 1) ^ ((tmp & 1) * poly);
|
||||
return crc = tmp;
|
||||
}
|
||||
TYPE operator()(uint8_t data)
|
||||
{
|
||||
TYPE tmp = crc ^ data;
|
||||
crc = lut[tmp & 255];
|
||||
for (int k = 1; k < BYTES; ++k)
|
||||
crc ^= lut[(k << 8) + ((tmp >>= 8) & 255)];
|
||||
return crc;
|
||||
}
|
||||
template <typename DATA>
|
||||
TYPE operator()(DATA data)
|
||||
{
|
||||
for (int i = sizeof(data); i; --i) {
|
||||
(*this)((uint8_t)data);
|
||||
data >>= 8;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
uint16_t CRC<uint16_t>::operator()(uint8_t data)
|
||||
{
|
||||
uint16_t tmp = crc ^ data;
|
||||
return crc = lut[256 + (tmp >> 8)] ^ lut[tmp & 255];
|
||||
}
|
||||
|
||||
template<>
|
||||
uint8_t CRC<uint8_t>::operator()(uint8_t data)
|
||||
{
|
||||
return crc = lut[crc ^ data];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue