Files
mir_server/sdk/utils/CRC16.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

88 lines
2.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************************
* crc16的checksum计算
* 如果g_ulTable没有初始化第一次使用的时候将初始化
***********************************************************/
#define CRC16_POLYNOMIAL 0x1021 // CRC_16校验方式的多项式.
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
static ulong g_ulTable[256];
static bool has_inited = false;
#include "_osdef.h"
// CRC_16方式校验的初始化函数, 计算CRC_16余数表.
void CRC16Init(void)
{
if (has_inited) return;
uint nRemainder;
int n, m;
ulong *pulTable = g_ulTable;
for(n = 0; n < 256; n ++)
{
nRemainder = (uint)n << 8;
for(m = 8; m > 0; m --)
{
if(nRemainder & 0x8000)
{
nRemainder = (nRemainder << 1) ^ CRC16_POLYNOMIAL;
}
else
{
nRemainder = (nRemainder << 1);
}
}
*(pulTable + n) = nRemainder;
}
has_inited =true;
}
// 反转数据的比特位, 反转后MSB为1.
// 反转前: 1110100011101110 0010100111100000
// 反转后: 1111001010001110 1110001011100000
unsigned int CRCBitReflect(ulong ulData, int nBits)
{
ulong ulResult = 0x00000000L;
int n;
for(n = 0; n < nBits; n ++)
{
if(ulData & 0x00000001L)
{
ulResult |= (ulong)(1L << ((nBits - 1) - n));
}
ulData = (ulData >> 1);
}
return(ulResult);
}
// 以CRC_16方式计算一个数据块的CRC值.
// pucData - 待校验的数据块指针.
// nBytes - 数据块大小, 单位是字节.
// 返回值是无符号的长整型, 其中低16位有效.
unsigned int CRC16Calc( unsigned char *pucData, size_t nBytes)
{
uint nRemainder, nRet;
uchar index;
if (has_inited ==false)
{
CRC16Init(); //如果没有初始化就初始化以下
}
ulong *pulTable = g_ulTable;
nRemainder = 0x0000;
for(size_t n = 0; n < nBytes; n ++)
{
index = (uchar)CRCBitReflect(*(pucData + n), 8) ^ (nRemainder >> 8);
nRemainder = (uint)*(pulTable + index) ^ (nRemainder << 8);
}
nRet = (uint)CRCBitReflect(nRemainder, 16) ^ 0x0000;
return(nRet);
}