CRC16、CRC32校验简单分析

合集下载

java crc3216进制数校验算法

java crc3216进制数校验算法

java crc3216进制数校验算法Java CRC32是一种校验算法,用于对数据进行校验和验证。

CRC32是循环冗余校验码的32位实现,它通过对数据进行多项式除法运算来生成一个32位的校验值。

本文将详细介绍Java CRC32算法的原理、应用及其实现方式。

一、CRC32校验算法原理CRC32算法是一种循环冗余校验码算法的32位实现。

它通过对数据进行多项式除法运算,得到一个32位的校验值。

具体的原理如下:1. 初始化CRC寄存器的值为全1(32个1)。

2. 将要校验的数据的每个字节与CRC寄存器的值进行异或运算。

3. 将CRC寄存器的值右移8位,并用一个预设的多项式(通常是0xEDB88320)进行异或运算。

4. 重复步骤2和3,直到所有的数据字节都被处理过。

5. 最终得到的CRC寄存器的值即为校验值。

二、CRC32校验算法应用CRC32校验算法在数据传输和存储中广泛应用,其中一些常见的应用包括:1. 数据完整性校验:通过计算数据的CRC32校验值,可以验证数据在传输或存储过程中是否发生了错误或损坏。

2. 文件校验:在下载文件或拷贝文件时,可以通过比较源文件和目标文件的CRC32校验值来判断文件是否完整无误。

3. 网络通信:在网络通信中,通过计算发送数据的CRC32校验值,接收方可以验证接收到的数据的完整性。

4. 数据库校验:在数据库中存储数据的同时,可以计算数据的CRC32校验值,并将其与存储的数据一起存储。

当需要读取数据时,可以通过比较计算得到的CRC32校验值和存储的校验值来验证数据的完整性。

三、Java CRC32算法实现Java提供了java.util.zip.CRC32类来实现CRC32校验算法。

下面是一个使用Java CRC32算法计算校验值的示例代码:```javaimport java.util.zip.CRC32;public class CRC32Example {public static void main(String[] args) {byte[] data = "Hello, CRC32!".getBytes();CRC32 crc32 = new CRC32();crc32.update(data);long checksum = crc32.getValue();System.out.println("CRC32 checksum: " + checksum);}}```在上述示例代码中,首先将要校验的数据转换为字节数组。

16位循环冗余校验码_CRC_的原理和性能分析

16位循环冗余校验码_CRC_的原理和性能分析

16位循环冗余校验码_CRC_的原理和性能分析16位循环冗余校验码(CRC)是一种广泛应用于数据传输中的错误检测码。

它通过使用除法运算和异或运算来生成一个冗余校验码,并将其附加到数据上。

接收方在接收到数据后,通过同样的计算方式对数据进行校验,然后与接收到的校验码进行比较,从而判断数据是否存在错误。

CRC的原理如下:1.选择一个特定的多项式作为生成器多项式G(x),通常以二进制方式表示。

2.将数据D(x)乘以x的n次方,其中n为生成器多项式的次数。

3.将上述结果除以生成器多项式G(x),并将余数作为冗余校验码。

具体的计算过程如下:1.将生成器多项式转换为二进制数,作为一个校验位模型。

2.将数据与n个0相接,使其长度与生成器多项式的次数一致。

3.将上述结果除以生成器多项式,并将余数作为冗余校验码。

性能分析:1.理论上,CRC能够探测所有偶数个错误位和绝大多数奇数个错误位。

但由于CRC运算时使用的是模2除法,因此会漏掉部分奇数个错误位。

2.CRC的检错性能与生成器多项式的选择相关。

选择一个好的生成器多项式很重要,能够提高CRC的检错能力。

3.16位的CRC校验码相对于32位或更多位的CRC校验码来说,冲突概率较高。

这意味着可能存在不同的数据产生相同的校验码。

因此,在应用中,需要根据实际情况选择合适的CRC位数。

总结:16位循环冗余校验码通过除法运算和异或运算生成一个冗余校验码,用于检测数据传输中的错误。

它的性能取决于生成器多项式的选择,能够探测大部分的错误位。

然而,由于CRC采用模2除法,可能会漏掉部分奇数个错误位。

在应用中,需要根据实际情况选择合适的CRC位数。

CRC校验解读

CRC校验解读
crc.c[0] = crc.c[1]^crctableh[t];
crc.c[1] = crctablel[t];
n--;
buf++;
}
return ( crc.x );
}
表面上看起来,函数crc1比crc0的源代码还长一些。但是编译后,函数crc1的目标代码实际为44个字节,加上表格占用的512个字节,一共使用了556个字节,比函数crc0反而节约了24个字节。这两个函数的运行对比情况见表一。
计算CRC校验时,最常用的计算方式有三种:查表、计算、查表+计算。一般来说,查表法最快,但是需要较大的空间存放表格;计算法最慢,但是代码最简洁、占用空间最小;而在既要求速度,空间又比较紧张时常用查表+计算法。
下面我们分别就这三种方法进行讨论和比较。这里以使用广泛的51单片机为例,分别用查表、计算、查表+计算三种方法计算1021多项式(CRC-ITU)校验。原始程序都是在网上或杂志上经常能见到的,相信大家也比较熟悉了,甚至就是正在使用或已经使用过的程序。
crc ^= crc_ta[da^(*ptr&0x0f)];/* CRC的高4位和本字节的后半字节相加后查表*/
/*计算CRC,然后再加上上一次CRC的余数*/
ptБайду номын сангаас++;
}
return crc;
}
程序优化策略:上面程序都只是给出了通用算法,并没有考虑到51单片机的特点。我们知道,51单片机是8位单片机,使用的变量类型也是8位的。如果在程序中使用8位的变量速度是最快的,比使用16位的变量代码短、效率高。在上面的程序中都使用了大量整型数类型(16位)的表格和整型数类型的变量,特别是关键的变量。如果我们不使用整型类型的表格和变量,而使用字节类型的表格和变量,就能够使程序的性能得到优化。基于这种思路,我们将原来整型的表格拆分为两个字节型(8位)的表格,即将原来表格的高低字节分别拆开,每个表格还是256个单元,这样表格的大小和顺序都没有变;原来使用16位变量计算的地方,改用8位变量计算。

最详细易懂的CRC-16校验原理(附源程序)

最详细易懂的CRC-16校验原理(附源程序)

最详细易懂的CRC-16校验原理(附源程序)1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。

2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。

例如:代码对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。

标准CRC生成多项式如下表:名称生成多项式简记式* 标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8 x8+x6+x4+x3+x2+x1 0x5ECRC-12 x12+x11+x3+x+1 80FCRC-16 x16+x15+x2+1 8005 IBM SDLCCRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCSCRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP3、CRC-16校验码的使用:现选择最常用的CRC-16校验,说明它的使用方法。

根据Modbus协议,常规485通讯的信息发送形式如下:地址功能码数据信息校验码1byte 1byte nbyte 2byteCRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。

例如:信息字段代码为: 1011001,校验字段为:1010。

发送方:发出的传输字段为: 1 0 1 1 0 0 1 1 0 10信息字段校验字段接收方:使用相同的计算方法计算出信息字段的校验码,对比接收到的实际校验码,如果相等及信息正确,不相等则信息错误;或者将接受到的所有信息除多项式,如果能够除尽,则信息正确。

crc16 校验 查表法

crc16 校验 查表法

crc16 校验查表法CRC16校验是一种常用的校验方法,通过查表法实现。

在数据通信中,数据的完整性和准确性是非常重要的,而CRC16校验能够帮助我们检测数据是否出现错误或被篡改。

本文将详细介绍CRC16校验的原理和实现方法。

一、CRC校验简介CRC(Cyclic Redundancy Check)校验是一种基于多项式运算的校验方法,常用于数据通信中的差错检测。

它通过对待校验数据进行一系列的位运算,生成一个与数据长度无关的校验码。

接收方在接收到数据后,同样进行CRC运算,将得到的校验码与发送方发送的校验码进行比对,如果一致,则说明数据在传输过程中没有发生错误。

二、CRC16校验原理CRC16校验是CRC校验的一种,它使用16位的多项式进行计算。

CRC16校验的原理是将待校验数据和一个预设的除数(生成多项式)进行一系列的位运算,最后得到一个16位的校验码。

具体过程如下:1. 预设除数:CRC16校验使用的预设除数是一个16位的二进制数,常用的有多个不同的预设除数,如0x8005、0x1021等。

2. 数据填充:在待校验数据的末尾填充16个0,使得待校验数据的位数和预设除数的位数一致。

3. 初始值设置:将初始值设为全1的16位二进制数。

4. 逐位异或运算:从待校验数据的最高位开始,逐位与初始值进行异或运算,如果结果为1,则将初始值右移一位并与预设除数进行异或运算,如果结果为0,则直接右移一位。

5. 重复上述步骤,直到待校验数据的所有位都进行了异或运算。

6. 得到校验码:最后得到的16位二进制数即为CRC16校验码。

三、CRC16查表法实现CRC16校验的查表法实现相对于位运算的实现更加高效。

查表法的基本思想是将预设除数的所有可能取值及其对应结果存储在一个查表数组中,通过查表的方式来进行CRC16校验的计算。

1. 初始化CRC表:首先需要创建一个256个元素的CRC表,每个元素的值为该位二进制数的CRC16校验码。

C#硬件校验数据校验算法C#Crc16Crc16CCITTCRC16FORX25CRC32

C#硬件校验数据校验算法C#Crc16Crc16CCITTCRC16FORX25CRC32

C#语言CRC数据校验算法目录C#语言CRC数据校验算法 (1)前言 (1)Crc16 (2)Crc16CCITT和Crc16CCITT_False (5)Crc16FORX25 (6)Crc32 (7)赠送常用字节算法 (9)源码文件 (11)前言每个算法都经过验证的,都是在硬件采集上使用过,除了Crc32算法没验证外,其它算法请放心使用附C#源码文件。

(文档末尾有源码文件)Crc16#region crc16public static string GetCrc16(string data){byte[] bs = StrToToHexByte(data);string crc16 = Get_CRC16_C(bs);string crc16_r = string.Format("{0} {1}", crc16.Substring(2, 2),crc16.Substring(0, 2));bs = null;crc16 = null;return crc16_r;}public static string ReverseCrc16(string crc16){string crc16Reverse = string.Format("{0} {1}", crc16.Substring(2, 2), crc16.Substring(0, 2));return crc16Reverse;}///<summary>///字符串转16进制字节数组///</summary>///<param name="hexString"></param>///<returns></returns>public static byte[] StrToToHexByte(string hexString){hexString = hexString.Replace(" ", "");if ((hexString.Length % 2) != 0)hexString = string.Format("{0} ", hexString);byte[] returnBytes = new byte[hexString.Length / 2];for (int i = 0; i < returnBytes.Length; i++)returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);return returnBytes;}///<summary>///字节数组转16进制字符串///</summary>///<param name="bytes"></param>///<returns></returns>public static string ByteToHexStr(byte[] bytes){string returnStr = "";if (bytes != null){for (int i = 0; i < bytes.Length; i++){returnStr = string.Format("{0}{1}", returnStr, bytes[i].ToString("X2"));}}return returnStr;}///<summary>///计算CRC校验码,并转换为十六进制字符串/// Cyclic Redundancy Check 循环冗余校验码///是数据通信领域中最常用的一种差错校验码///特征是信息字段和校验字段的长度可以任意选定///</summary>///<param name="data"></param>///<returns></returns>public static string Get_CRC16_C(byte[] data){byte num = 0xff;byte num2 = 0xff;byte num3 = 1;byte num4 = 160;byte[] buffer = data;for (int i = 0; i < buffer.Length; i++){//位异或运算num = (byte)(num ^ buffer[i]);for (int j = 0; j <= 7; j++){byte num5 = num2;byte num6 = num;//位右移运算num2 = (byte)(num2 >> 1);num = (byte)(num >> 1);//位与运算if ((num5 & 1) == 1){//位或运算num = (byte)(num | 0x80);}if ((num6 & 1) == 1){num2 = (byte)(num2 ^ num4);num = (byte)(num ^ num3);}}}return ByteToHexStr(new byte[] { num, num2 }, 2);}///<summary>///获取并校验两数据是否一致///</summary>///<param name="srcData"></param>///<param name="desData"></param>///<returns></returns>public static bool CheckCRC(byte[] srcData, byte[] desData) {string crc = Get_CRC16_C(srcData);if (crc == ByteToHexStr(desData, desData.Length))return true;elsereturn false;}///<summary>///字节数组转16进制字符串///</summary>///<param name="bytes"></param>///<returns></returns>public static string ByteToHexStr(byte[] bytes, int size) {string returnStr = "";if (bytes != null){for (int i = 0; i < size; i++){returnStr = string.Format("{0}{1}", returnStr, bytes[i].ToString("X2"));}}return returnStr;}#endregion crc16Crc16CCITT和Crc16CCITT_False#region Crc16CCITTpublic static string ConvertToHEX(int dec){return dec.ToString("X");}public static string GetCrc16CCITT_False(string hexString){string hex = ConvertToHEX(crc16(StrToToHexByte(hexString))).PadLeft(4, '0');string crc = ReverseCrc16(hex);return crc;}public static int crc16(byte[] bytes){return crc16(bytes, bytes.Length);}public static int crc16(byte[] bytes, int len){int crc = 0xFFFF;for (int j = 0; j < len; j++){crc = ((crc >> 8) | (crc << 8)) & 0xffff;crc ^= (bytes[j] & 0xff);// byte to int, trunc signcrc ^= ((crc & 0xff) >> 4);crc ^= (crc << 12) & 0xffff;crc ^= ((crc & 0xFF) << 5) & 0xffff;}crc &= 0xffff;return crc;}public static int crc16(byte[] bytes, int start, int len){int crc = 0xFFFF;for (; start < len; start++){crc = ((crc >> 8) | (crc << 8)) & 0xffff;crc ^= (bytes[start] & 0xff);// byte to int, trunc signcrc ^= ((crc & 0xff) >> 4);crc ^= (crc << 12) & 0xffff;crc ^= ((crc & 0xFF) << 5) & 0xffff;}crc &= 0xffff;return crc;}public static short crc16_short(byte[] bytes){return crc16_short(bytes, 0, bytes.Length);}public static short crc16_short(byte[] bytes, int len){return (short)crc16(bytes, len);}public static short crc16_short(byte[] bytes, int start, int len) {return (short)crc16(bytes, start, len);}#endregion Crc16CCITTCrc16FORX25#region CRC16FORX25public static byte[] CRC_16forx25(byte[] bytes){byte[] returnVal = new byte[2];int i, j, lsb;int h = 0xffff;for (i = 0; i < bytes.Length; i++){h ^= bytes[i];for (j = 0; j < 8; j++){lsb = h & 0x0001; //取 CRC 的移出位h >>= 1;if (lsb == 1){h ^= 0x8408;}}}h ^= 0xffff;returnVal[1] = (byte)(h >> 8);//CRC高位returnVal[0] = (byte)(h & 0x00ff);//CRC低位return returnVal;}#endregion CRC16FORX25Crc32#region crc32public class CRC32{static UInt32[] crcTable = {0x0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535,0x9e6495a3,0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07,0x90bf1d91,0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5,0xe8b8d433,0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97,0xe6635c01,0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615,0x73dc1683,0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27,0x7d079eb1,0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713,0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21,0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,};public static byte[] GetCrc32(byte[] bytes){//e6dda9daint crc = GetCRC32(bytes);string str = Convert.ToString(crc, 16).ToUpper();byte[] b4 = new byte[4];b4[0] = Convert.ToByte(str.Substring(6), 16);b4[1] = Convert.ToByte(str.Substring(4, 2), 16);b4[2] = Convert.ToByte(str.Substring(2, 2), 16);b4[3] = Convert.ToByte(str.Substring(0, 2), 16);return b4;}public static int GetCRC32(byte[] bytes){int iCount = bytes.Length;UInt32 crc = 0xFFFFFFFF;for (int i = 0; i < iCount; i++){crc = ((crc >> 8) & 0x00FFFFFF) ^ crcTable[(crc ^ bytes[i]) & 0xFF];}UInt32 temp = crc ^ 0xFFFFFFFF;int t = (int)temp;return (t);}}#endregion赠送常用字节算法public static int LastIndexOf(byte[] data, byte[] find){if (find == null || find.Length == 0)return -1;int pos = -1;for (int i = data.Length; i >= find.Length; i--){bool isFind = true;for (int j = 0; j < find.Length; j++){if (find[j] != data[i - (find.Length - j)]){isFind = false;break;}}if (isFind){pos = i - find.Length;break;}}return pos;}public static int IndexOf(byte[] data, byte[] find){if (find == null || find.Length == 0)return -1;if (find.Length > data.Length)return -1;int pos = -1;for (int i = 0; i < data.Length; i++){if (data.Length - i >= find.Length){bool isFind = true;for (int j = 0; j < find.Length; j++){if (find[j] != data[i + j]){isFind = false;break;}}if(isFind){pos = i;break;}}}return pos;}public static int LastIndexOf(List<byte> data, byte[] find) {if (find == null || find.Length == 0)return -1;int pos = -1;for (int i = data.Count; i >= find.Length; i--){bool isFind = true;for (int j = 0; j < find.Length; j++){if (find[j] != data[i - (find.Length - j)]){isFind = false;break;}}if (isFind){pos = i - find.Length;break;}}return pos;}//是否能通过crc校验public static bool IsCrc16Pass(string fullData){if (fullData.Length >= 6){string data = fullData.Substring(0, fullData.Length - 5).Trim();string crc16 = fullData.Substring(fullData.Length - 5);string calcCrc16 = GetDefalutCrc16(data);string calcCrc16Rev = ReverseCrc16(calcCrc16);return crc16.Replace(" ", "") == calcCrc16.Replace(" ", "") || crc16.Replace(" ", "") == calcCrc16Rev.Replace(" ", "");}return false;}文件CrcHelper.cs。

CRC16和CRC32探讨

CRC16和CRC32探讨

CRC16和CRC32探讨再探CRC之前写了CRC16的程序,虽说能用,却不知其所心然,现在要用CRC32,重温一遍,一下就通了。

笔记如下CRC我没记错的话是Cyclic Redundancy Code,Cyclic 和Redundancy非常传神,所谓冗余就是附加的信息,这就是计算下面的原始数据时为什么原始数据要左移四位的原因,////// The simplest CRC implement algorithm.////*Load the register with zero bits.Augment the message by appending W zero bits to the end of it.While (more message bits)BeginShift the register left by one bit, reading the next bit of the augmented message into register bit position 0.If (a 1 bit popped out of the register during step 3)Register = Register XOR Poly.EndThe register now contains the remainder.*/#include ;#define POLY 0x13int main(){/// the dataunsigned short data = 0x035b;/// load the register with zero bitsunsigned short regi = 0x0000;/// augment the data by appending W(4) zero bits to the end of it.data ;= 0; -- cur_bit ){/// test the highest bit which will be poped later. /// in fact, the 5th bit from right is the hightest bit hereif( ( ( regi >;>; 4 ) & 0x0001 ) == 0x1 )//凑够5位数(与被除数即生成多项式的位数一样),模2除{regi = regi ^ POLY;}/// shift the register regi ;>; cur_bit ) & 0x0001; regi |= tmp;}/// and now, register contains the remainder which is also called CRC value.return 0;}以上程序就是上面照片里算法的模拟实现,步骤完全一致。

crc16校验范围

crc16校验范围

crc16校验范围摘要:1.CRC16校验简介2.CRC16校验的计算方法3.CRC16校验范围的概述4.CRC16校验在实际应用中的优势5.常见问题及解决方法正文:**CRC16校验简介**CRC16(Cyclic Redundancy Check 16)是一种循环冗余校验算法,用于检测数据传输或存储中的错误。

它通过在数据后面附加一些校验位,然后接收方在接收到数据后,通过相同的计算方法,对数据进行校验,以判断数据在传输过程中是否发生了改变或错误。

CRC16校验因其高效性和可靠性而在众多领域得到广泛应用。

**CRC16校验的计算方法**CRC16校验的计算方法主要包括以下几个步骤:1.初始化:设定初始值,通常是0。

2.按位异或:将数据位的反码与校验位进行异或操作。

3.迭代:根据预先设定的迭代次数,将校验位与生成多项式进行按位异或操作。

4.输出:得到最终的校验结果。

**CRC16校验范围的概述**CRC16校验范围是指在数据传输或存储中,能够有效检测到错误的一段数据长度。

在实际应用中,CRC16校验通常用于检测数据包或文件的正确性。

校验范围越大,检测的准确性越高,但同时也会增加数据的开销。

因此,在实际应用中,需要根据具体需求来选择合适的CRC16校验范围。

**CRC16校验在实际应用中的优势**CRC16校验在实际应用中具有以下优势:1.高效性:CRC16校验算法简单,计算速度快,适用于实时数据传输场景。

2.可靠性:CRC16校验能够检测到多种类型的错误,包括突发性错误和单个比特错误。

3.通用性:CRC16校验适用于不同类型的数据格式和传输协议。

**常见问题及解决方法**1.问题:CRC16校验出现误报怎么办?解决方法:检查生成多项式和迭代次数是否合适,适当调整以提高校验准确性。

2.问题:CRC16校验范围过大,导致数据开销增加怎么办?解决方法:可以选择更小的生成多项式和迭代次数,以减小校验范围。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

CRC16校验分析
工业通讯中传输的数据一般是先传数据字节的低位,如:实际DATA 0x38 (0011 1000) 接收端收到为0001 1100 (0x1C),所以大部分CRC校验是处理颠倒的字节数据。

有的多项式简式为0x1021(本文以0x8005为主),目前主要的CRC算法有查表法和直接计算:
1.直接计算
由于数据是颠倒的所以生成项亦要倒置:0xa001(原生成多项式CRC码为0x18005,最高位始终为1故简写为0x8005,反置得到0xa001。

计算CRC时也要从其低位开始运算,且计算中数据右移(移出高位)。

异或运算满足交换律:(A^B)^C=A^(B^C),下面分析其中一种简单算法:
C语言计算:
计算时一次计算8bits,数据与CRC生成多项式(简式)相除,除不尽的余数与下8bits数据再异或(相减),接着进入下一8bits计算。

直到len长的数据全部计算完。

2.查表法:
通过分别计算8bits(查表得到其余式)来实现逐个字节数据的
CRC
计算,直到全部字节数据计算完最后的余式就是CRC。

下面全是8bits查询表(256个余式的表)
,不过也可以4bits查询一次的计算(这样表里只需16个余式).先看程序的算法:
r=0; //r是寄存器,先初始化为0
//p0),t是查询表
字节数据
查询r高8位对应的余式,再
与新得到的式子异或
数据计算示意图:

之后再重复上面的步骤
……若待测数据未扩展0,则此时还要计算4字节扩展0的CRC:
构造CRC32查询表:
一般来说,计算CRC是用“直驱表法”算法计算的,它与上面的算法非常相似,下面分析它的计算:计算步骤为(摘自文献):
1. Shift the register left by one byte
2. XOR the top byte just rotated out of the register with the next message byte
to yield an index into the table ([0,255]).
3. XOR the table value into the register.
4. Goto 1 iff more augmented message bytes.
C语言算法为:
r=0; //r是寄存器,先初始化为0
while (len--) //len是待测数据(不用扩展0)的字节长度
r = (r<<8) ^ t[(r >> 24) ^ *p++]; //p是指向待测数据的指针,t是查询表
相当于通过移位处理了8 个bit 的数据,相当于把之前的CRC 码的高字节(8bit)全部移出,与一个byte 的数据做XOR 运算,根据运算结果来选择一个值(称为余式),与原来的CRC 码再做一次XOR 运算,就可以得到新的CRC 码。

p指向Ⅰ、Ⅱ、Ⅲ、Ⅳ、Ⅴ、Ⅵ……字节数据,r为CRC32余式值,t为查询表。

实际上收到的数据一般是先收数据的低位,最后收到字节数据的高位,这样将数据反置了,于是算法只需稍作更改也可算出:
1. 将寄存器向右移动一个字节。

2. 将刚移出的那个字节与待测数据中的新字节做XOR运算,得到一个指向查询表的索引值。

3. 将索引所指的表值与寄存器做XOR运算。

4. 如数据没有全部处理完,则跳到步骤1。

算法为:
r=0; //r是寄存器,先初始化为0
for(i=0; i <len; i++) //len是待测数据(不用扩展0)的字节长度
{
r = t[( r^(*(p+i)) ) & 0xff] ^ (r >> 8); //p是指向待测数据的指针,t是查询表
}
注意此时的查询表不再是前文那个查询表了,它也是一个颠倒的查询表:。

相关文档
最新文档