crc16算法
1. 请教一个crc16校验算法的问题:程序每句话是什么意思,做什么用的,急用!!谢谢~~
以下内容可能对你有用呀。好好看看就明白了。
CRC校验
采用CRC-16,即2字节冗余循环码CRC,低字节在前。CRC码由发端计算,放置于发送消息帧的尾部,接收端再重新计算接收到信息的CRC码,比较计算得到的CRC码是否与接收到的相符,若不符则表明出错。CRC码的计算包括整个消息内容,计算时只用8位数据位,而起始位、停止位及可能的校验位均不参与CRC计算。
CRC校验可以100%检测出所有奇数个随机错误。CRC-16校验可以检测出长度小于等于16的突发错误,可以保证在1014 bit码元中只含有1位未被检测出的错误。CRC-16的具体算法有多种,以下是一个例子。
1.置16位寄存器为全1,作为CRC寄存器。
2.把一个8位数据与16位CRC寄存器的低字节相异或,把结果放于CRC寄存器中。
3.把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位(移出位)。
4.如果最低位为0,重复③(再移位);如果最低位为1,CRC寄存器与多项式A001H(1010 0000 0000 0001)进行异或。
5.重复③、④,直到右移8次,这样整个8位数据全部进行了处理。
6.重复②-⑤,进行下一个8位数据的处理。
7.将一帧的所有数据字节处理完后得到CRC-16寄存器。
8.将CRC-16寄存器的低字节和高字节交换,得到的值即为CRC-16码。
2. CRC码的计算方法
给信息码补5个0,然后去除多项式,余数就是较验码
3. CRC 16 校验,如何计算多项式
方法如下:
CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或(异或:二进制运算 相同为0,不同为1;0^0=0;0^1=1;1^0=1;1^1=0), 之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果LSB为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。 3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
CRC(16位)多项式为 X16+X15+X2+1,其对应校验二进制位列为1 1000 0000 0000 0101。
4. crc-16校验码的计算方法
占位顺求答案
5. crc16的算法
#define
CRC16_POLYNOMIAL
0x1021
//
CRC_16校验方式的多项式.
typedef
unsigned
char
uchar;
typedef
unsigned
int
uint;
typedef
unsigned
long
ulong;
typedef
enum
tagBoolean
{
FALSE,
TRUE
}
bool;
ulong
g_ulTable[256];
//
CRC_16方式校验的初始化函数,
计算CRC_16余数表.
void
_far
CRC16Init(void)
{
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;
}
}
//
以CRC_16方式计算一个数据块的CRC值.
//
pucData
-
待校验的数据块指针.
//
nBytes
-
数据块大小,
单位是字节.
//
返回值是无符号的长整型,
其中低16位有效.
ulong
_far
CRC16Calc(uchar
*pucData,
int
nBytes)
{
uint
nRemainder,
nRet;
int
n;
uchar
index;
ulong
*pulTable
=
g_ulTable;
nRemainder
=
0x0000;
for(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);
}
//
反转数据的比特位,
反转后MSB为1.
//
反转前:
1110100011101110
0010100111100000
//
反转后:
1111001010001110
1110001011100000
ulong
_far
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);
}
6. 几种CRC16算法
一. CRC16算法首先在源文件头文件加入表值:[c] view plain ////////////////////////////////////////////////////////////////////////// // CRC16码表 static WORD const wCRC16Table[256] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040}; 然后在文件中加入下列函数:[c] view plain ////////////////////////////////////////////////////////////////////////// // 函数功能: CRC16效验 // 输入参数: pDataIn: 数据地址 // iLenIn: 数据长度 // 输出参数: pCRCOut: 2字节校验值 void CCRCDlg::CRC16(const CHAR* pDataIn, int iLenIn, WORD* pCRCOut) { WORD wResult = 0; WORD wTableNo = 0; for(int i = 0; i < iLenIn; i++) { wTableNo = ((wResult & 0xff) ^ (pDataIn[i] & 0xff)); wResult = ((wResult >> 8) & 0xff) ^ wCRC16Table[wTableNo]; } *pCRCOut = wResult; } 二.CRC16(MODBUS)[c] view plain ////////////////////////////////////////////////////////////////////////// // CRC MODBUS 效验 // 输入参数: pDataIn: 数据地址 // iLenIn: 数据长度 // 输出参数: pCRCOut: 2字节校验值 void CCRCDlg::CheckCRCModBus(const CHAR* pDataIn, int iLenIn, WORD* pCRCOut) { WORD wHi = 0; WORD wLo = 0; WORD wCRC; wCRC = 0xFFFF; for (int i = 0; i < iLenIn; i++) { wCRC = CalcCRCModBus(*pDataIn, wCRC); pDataIn++; } wHi = wCRC / 256; wLo = wCRC % 256; wCRC = (wHi > 1; wCRCIn = wCRCIn & 0x7fff; if(wCheck == 1) { wCRCIn = wCRCIn ^ 0xa001; } wCRCIn = wCRCIn & 0xffff; } return wCRCIn; } 三.CRC16(CCITT的0XFFFF)[c] view plain ////////////////////////////////////////////////////////////////////////// // 函数功能: CRC16效验(CCITT的0XFFFF效验) // 输入参数: pDataIn: 数据地址 // iLenIn: 数据长度 // 输出参数: pCRCOut: 2字节校验值 void CCRCDlg::CRCCCITT(const CHAR* pDataIn, int iLenIn, WORD* pCRCOut) { WORD wTemp = 0; WORD wCRC = 0xffff; for(int i = 0; i < iLenIn; i++) { for(int j = 0; j < 8; j++) { wTemp = ((pDataIn[i] > 8); wCRC
7. CRC-16/MODBUS计算详细步骤
CRC-16/MODBUS 校验位计算 - CSDN博客CRC-16 / MODBUS 校验计算方法
8. 请将CRC16的C语言算法,改造为JAVA语言算法,万分感谢!
public static int CRC16(byte[] Buf, int Len) {
int CRC;
int i, Temp;
CRC = 0xffff;
for (i = 0; i < Len; i++) {
CRC = CRC ^ byteToInteger(Buf[i]);
// System.out.println(byteToInteger(Buf[i]));
for (Temp = 0; Temp < 8; Temp++) {
if ((CRC & 0x01) == 1)
CRC = (CRC >> 1) ^ 0xA001;
else
CRC = CRC >> 1;
}
}
return CRC;
}
9. CRC16校验码如何计算
首先G(X)=X3+X+1可以得出G(x)=1011[G(x)中的1就是二进制第0位为1,X就是第一位为1,没有X^2,所以第二位为0,X^3则第三位为1。所以就是1011]
M(x)=0011M(x)*x3=0011000
M(x)*x3/G(x)的余数是101所以R(X)=101
CRC码为:M(x)*x3+R(x)=0011000+010=0011010
在计算机网络通信中
运用CRC校验时相对于其他校验方法就有一定的优势。CRC可以高比例的纠正信息传输过程中的错误,可以在极短的时间内完成数据校验码的计算,并迅速完成纠错过程,通过数据包自动重发的方式使得计算机的通信速度大幅提高,对通信效率和安全提供了保障。由于CRC算法检验的检错能力极强,且检测成本较低,因此在对于编码器和电路的检测中使用较为广泛。
以上内容参考:网络-CRC
10. CRC16检验算法
public class CRC16 {
public static String getData(String data){
byte[] b=data.getBytes();
short crc=0;
for(int n=0;n<b.length;n++){
for (char i = 0x80; i != 0; i >>= 1)
{
if ((crc&0x8000) != 0)
{
crc <<= 1;
crc ^= 0x1021;
}
else
{
crc <<= 1;
}
if ((b[n]&i) != 0)
{
crc ^= 0x1021;
}
}
}
return Integer.toHexString(crc & 0xFFFF);
}
public static void main(String[] args) {
System.out.println(CRC16.getData("1234567890"));
}
}这个肯定可以 我自己测试通过的