-
Notifications
You must be signed in to change notification settings - Fork 1
/
CRCcalculation_Library.cpp
165 lines (156 loc) · 5.71 KB
/
CRCcalculation_Library.cpp
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* CRCcalculation_Library.cpp : Defines the functions for the static library.
This file is part of CRCcalculation_Library which is a free software : you can redistribute itand /or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
CRCcalculation_Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
https://github.com/tanel312 www.tanels.com [email protected]
*/
#include "pch.h"
#include "framework.h"
#include "CRCcalculation_Library.h"
#include "ListOfPolynomials.h"
// Mode can be one of followings;
#define CRC8 0
#define CRC16 1
#define CRC24 2
#define CRC32 3
#define CRC40 4
#define CRC64 7
uint64_t const Mask[8] = { 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF, 0xFFFFFFFFFF, 0, 0, 0xFFFFFFFFFFFFFFFF };
uint64_t const Msbcheck[8] = { 0x80, 0x8000, 0x800000, 0x80000000, 0x8000000000, 0, 0, 0x8000000000000000 };
uint8_t const Shifter[8] = { 0, 8, 16, 24, 32, 0, 0, 56 };
/*-------------------------------------------------------------------------------
Reflect
Reflects the input (mirroring)
Inputs: Width
Input/Output: Inp
-------------------------------------------------------------------------------*/
void Reflect(uint64_t* Inp, uint8_t Width)
{
uint64_t tmp = ((uint64_t)Width / 8) - 1;
uint64_t mask = Msbcheck[tmp];
tmp = *Inp;
*Inp = 0;
while (Width--)
{
if (tmp & 1L)
*Inp |= mask;
tmp >>= 1;
mask >>= 1;
}
return;
}
/*-------------------------------------------------------------------------------
CreateCRCtable
Creates CRC Lookup Table
Inputs: Polynomial, Width
Output: CrcTable
-------------------------------------------------------------------------------*/
void CreateCRCtable(uint64_t* CrcTable, uint64_t Polynomial, uint8_t Width)
{
uint64_t index;
uint64_t value;
uint8_t cnt;
uint8_t mode = Width / 8 - 1;
for (index = 0; index < 256; index++)
{
value = ((index << Shifter[mode]) & Mask[mode]);
cnt = 8;
while (cnt--)
{
value = ((value & Msbcheck[mode]) == 0) ? (value << 1) : (value << 1) ^ Polynomial;
value &= Mask[mode];
}
CrcTable[index] = value;
}
}
/*-------------------------------------------------------------------------------
CreateCRCtableReflected
Creates CRC Reflected Lookup Table
Inputs: Polynomial, Width
Output: CrcTable
-------------------------------------------------------------------------------*/
void CreateCRCtableReflected(uint64_t* CrcTable, uint64_t Polynomial, uint8_t Width)
{
uint64_t index;
uint64_t value, tmp;
uint8_t cnt;
uint8_t mode = Width / 8 - 1;
uint64_t polynomalR = Polynomial;
Reflect(&polynomalR, Width);
for (index = 0; index < 256; index++)
{
value = 0;
tmp = index;
cnt = 8;
while (cnt--)
{
value = (((value ^ tmp) & 0x1) == 0) ? (value >> 1) : (value >> 1) ^ polynomalR;
value &= Mask[mode];
tmp >>= 1;
}
CrcTable[index] = value;
}
return;
}
/*-------------------------------------------------------------------------------
CalculateCRC
Calculates the CRC iaw selected type
Inputs: Buffer, Length, CrcTable, Width, Initialcrc, Initialrefl, XORout
Output: function returns
-------------------------------------------------------------------------------*/
uint64_t CalculateCRC(uint8_t* Buffer, uint64_t Length, uint64_t* CrcTable, uint8_t Width, uint64_t Initialcrc, bool Initialrefl, uint64_t XORout)
{
uint64_t crc = Initialcrc;
if (Initialrefl)
Reflect(&crc, Width);
uint8_t mode = Width / 8 - 1;
uint8_t index;
while (Length--)
{
index = (uint8_t)((crc >> Shifter[mode]) ^ *Buffer++);
crc = (mode == CRC8) ? (CrcTable[index]) : ((crc << 8) ^ CrcTable[index]);
}
return ((crc ^ XORout) & Mask[mode]);
}
/*-------------------------------------------------------------------------------
CalculateCRCreflected
Calculates the reflected CRC iaw selected type
Inputs: Buffer, Length, CrcTable, Width, Initialcrc, Initialrefl, XORout
Output: function returns
-------------------------------------------------------------------------------*/
uint64_t CalculateCRCreflected(uint8_t* Buffer, uint64_t Length, uint64_t* CrcTable, uint8_t Width, uint64_t Initialcrc, bool Initialrefl, uint64_t XORout)
{
uint64_t crc = Initialcrc;
if (Initialrefl)
Reflect(&crc, Width);
uint8_t mode = Width / 8 - 1;
while (Length--)
{
crc = (crc >> 8) ^ CrcTable[(crc ^ *Buffer++) & Mask[CRC8]];
}
return((crc ^ XORout) & Mask[mode]);
}
/*-------------------------------------------------------------------------------
CRC_Computation
Main function of CRC calculation library
Inputs: Input, Length, Type
Output: function
-------------------------------------------------------------------------------*/
uint64_t CRC_Computation(uint8_t* Input, uint64_t Length, uint8_t Type)
{
uint64_t crc;
uint64_t crctable[256];
if (CRCparams[Type].reflected == false)
{
// normal crc
CreateCRCtable(crctable, CRCparams[Type].normal, CRCparams[Type].width);
crc = CalculateCRC(Input, Length, crctable, CRCparams[Type].width, CRCparams[Type].initial, CRCparams[Type].initialrefl, CRCparams[Type].xorout);
}
else
{
// reflected crc
CreateCRCtableReflected(crctable, CRCparams[Type].normal, CRCparams[Type].width);
crc = CalculateCRCreflected(Input, Length, crctable, CRCparams[Type].width, CRCparams[Type].initial, CRCparams[Type].initialrefl, CRCparams[Type].xorout);
}
return crc;
}