C# CRC校验的一点感悟

今天在鼓捣一个手持操作器的时候,遇到一点问题,记录一下今天的经验包

由于之前公司产品在校验时基本上都是和校验,今天在准备用C#模拟一个古董操作器的时候,却遇到一个问题,模拟器发出的数据,主板一律不回复,对比通讯协议也没发现什么问题。由于文档有些不全,只是知道通讯格式,对比之后觉得应该是校验出了问题。由于CRC校验是数据通信领域最常用的校验方式,问了几个老家伙之后才知道这个四字节ASCII码校验和应该是CRC16-CCITT生成的,然后就去仔细看大学时候煞笔了很久也没明白的CRC校验的细节。

具体CRC如何生成我不阐述了,关键点在于“生成多项式”和初始值。

CRC16-CCITT的生成多项式是 0x1021;

不多说了,提供代码CRC16-CCITT类

public class Crc16Ccitt
    {
        public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }
        const ushort poly = 4129;
        ushort[] table = new ushort[256];
        ushort initialValue = 0;

        public Crc16Ccitt(InitialCrcValue initialValue)
        {
            this.initialValue = (ushort)initialValue;
            ushort temp, a;
            for (int i = 0; i < table.Length; ++i)
            {
                temp = 0;
                a = (ushort)(i << 8);
                for (int j = 0; j < 8; ++j)
                {
                    if (((temp ^ a) & 0x8000) != 0)
                    {
                        temp = (ushort)((temp << 1) ^ poly);
                    }
                    else
                    {
                        temp <<= 1;
                    }
                    a <<= 1;
                }
                table[i] = temp;
            }
        }

        public ushort ComputeChecksum(byte[] bytes)
        {
            ushort crc = this.initialValue;
            for (int i = 0; i < bytes.Length; ++i)
            {
                crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
            }
            return crc;
        }

        public ushort ComputeChecksum(List<byte> listTemp)
        {
            byte[] bytes = listToBytes(listTemp);
            ushort crc = this.initialValue;
            for (int i = 0; i < bytes.Length; ++i)
            {
                crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
            }
            return crc;
        }

        public byte[] ComputeChecksumBytes(byte[] bytes)
        {
            ushort crc = ComputeChecksum(bytes);
            return BitConverter.GetBytes(crc);
        }

        public byte[] listToBytes(List<byte> listTemp)
        {
            int length = listTemp.Count();
            byte[] bytes = new byte[length];
            for (int i = 0; i < length; i++)
            {
                bytes[i] = listTemp[i];
            }
            return bytes;
        }
    }

最后,请叫我红领巾

时间: 2024-08-24 00:42:30

C# CRC校验的一点感悟的相关文章

CRC校验程序3:通过窗体程序打开txt文件获取数据源,进行逐字节CRC校验

在上一篇中,生成输出的CRC.exe将要成为这个窗体应用的内置模块. 新建一个windows窗体应用程序,叫做CRClick.将应用程序CRC.exe从Console应用程序中找到,复制到CRClick文件夹的Debuge文件夹下.同时还有测试用的Test.txt. 打开窗体设计页面,插入两个Textbox和一个按钮,长度Textbox用来显示被校验的文件的绝对路径,短Textbox显示最终校验码.按钮激发选择文件的窗口.设计如下: 对于按钮的触发事件,我们生成一个OpenFileDialog控

Redis源码中的CRC校验码(crc16、crc64)原理浅析

在阅读Redis源码的时候,看到了两个文件:crc16.c.crc64.c.下面我抛砖引玉,简析一下原理. CRC即循环冗余校验码,是信息系统中一种常见的检错码.大学课程中的"计算机网络"."计算机组成"等课程中都有提及.我们可能都了解它的数学原理,在试卷上手工计算一个CRC校验码,并不是难事.但是计算机不是人,现实世界中的数学原理需要转化为计算机算法才能实现目的.实际上作为计算机专业背景人并不会经常使用或接触到CRC的计算机算法实现的原理,通常是电子学科背景的人士

CRC校验码的verilog实现与仿真结果

循环冗余校验码(CRC)的基本原理是: 将被处理的报文比特序列当做一个二进制多项式A(x)的系数,(任意一个由二进制位串组成的代码都可以和一个系数仅为'0'和'1'取值的多项式一一对应.例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111),该系数乘以2^n(n为生成多项式g(x)中x的最高次幂)以后再除以发送方和接收方事先约定好的生成多项式g(x)后,求得的余数P(x)就是CRC校验码,把它副到原始的报文A(x)后面形成新的报

CRC校验码原理、实例、手动计算

CRC16实现代码 思路:取一个字符(8bit),逐位检查该字符,如果为1,crc^crc_mul;同时,如果原本crc最高位是1,那么crc^crc_mul后左移1位,否则只是左移一位.计算完一个字符后,装入下一个字符. #include<stdio.h> #define crc_mul 0x1021 //生成多项式 unsigned int cal_crc(unsigned char *ptr, unsigned char len) { unsigned char i; unsigned

物联网平台设计心得:你所不知道的CRC校验

在物联网平台设计过程中,我的中间件一方面需要处理来自于硬件端的包,另一方面需要处理来自于用户端的包,用户端包括web端和手机端等等.所以编写一个统一的CRC认证是非常必须要. 那么,在设计开始,CRC认证到底是什么呢?所谓的CRC认证,就是指,在硬件端或者用户端进行数据传输前,通过一套算法,将待传输的数据,通过加验,算出其校验码,附加在包体的最后,然后中间件收到此包后,对包进行解析,拿出其中的数据内容部分,然后对包重新进行一次CRC加验,如果本次加验结果和包体附带的CRC校验码数据一致,那么就说

CRC校验程序2:通过命令提示符加载文本文档作为数据源进行CRC校验,输出校验码

将CRC校验函数封装在类中,通过控制台传参(文件的相对路径),进行CRC校验. 1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace CRC 9 { 10 class Program 11 { 12 static void Main(s

CRC校验

CRC校验,是对一个数据帧发送到对方时,对方能够正确的接收到这个数据帧的一种保证,保证接收到的数据帧是对的. CRC校验,一般占16位,两个字节.我们在发送一个数据帧的时候,对CRC校验前面那些位,用一种特殊的算法进行统计,算出来的数作为CRC校验这两个字节,填充到CRC这两个字节中.然后将数据帧发送出去.对方接收到这个数据帧的时候,将数据帧中的代表CRC校验的两个字节取出来,存下,然后自己对接收到的数据帧CRC校验前面的那些位进行和上面一样的算法进行统计,算出来的CRC校验和数据帧过来时带过来

最通俗的CRC校验原理剖析

http://winda.blog.51cto.com/55153/1063951 循环冗余校验码(CRC)的检错能力更强,可以检出多位错误. 1. CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端.当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数

CRC校验程序1:CRC循环冗余校验码计算

CRC全称Cyclic Redundancy Check,中文称为循环冗余检查.它是一种数据传输检错的机制,能够对数据进行多项式计算,并将得到的结果与接收设备共享,保证数据传输的正确性和完整性. 算法流程如下: 1. Load a 16-bit register with FFFF hex (all ‘1’s). Call this the CRC register. 2. Exclusive OR the first 8-bit byte of the message with the low