当前位置:首页 > 代码 > 正文

crc16代码(crc 代码)

admin 发布:2022-12-19 18:53 173


今天给各位分享crc16代码的知识,其中也会对crc 代码进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

CRC16校验码查表法的原理是什么?

基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。对于一个给定的(N,K)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。 校验码的具体生成过程为:假设要发送的信息用多项式C(X)表示,将C(x)左移R位(可表示成C(x)*xR),这样C(x)的右边就会空出R位,这就是校验码的位置。用 C(x)*xR 除以生成多项式G(x)得到的余数就是校验码。

任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。

php 实现crc16验证 modbus该如何实现?

在工业控制中,Modbus RTU CRC16的校验码用的比较广泛,包括本人富士产品中,PC与伺服电机以及PC与VP系列的变频器的Modbus RTU通讯中都使用到了CRC16.

而对CRC16的计算的方式基本上有2种:第一种,使用双循环依照CRC的计算方法进行计算,第二种,采用查表的方式。本人愚钝无比,从网络上搜来的查表法都与实际的正确CRC16的结果有所差异,因此编写了一个小程序供自己使用。

软件的界面很简单,输入诸如“010303020014”的值,然后每2个字符作为一个字节,填入字节数,然后就可以计算出校验码,校验码的多项式为:X16+X15+X2+1.

程序界面如下:

实现的源代码如下:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Edit1: TEdit;

Button1: TButton;

Edit2: TEdit;

Edit3: TEdit;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

Memo1: TMemo;

Label4: TLabel;

function CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

//××××××××××××××××××××××××××

// CalCRC16用于计算Modbus RTU的CRC16

// 多项式公式为X16+X15+X2+1

//××××××××××××××××××××××××××

function TForm1.CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;

const

GENP=$A001; //多项式公式X16+X15+X2+1(1100 0000 0000 0101)

var

crc:Word;

i:Integer;

tmp:Byte;

procedure CalOneByte(AByte:Byte); //计算1个字节的校验码

var

j:Integer;

begin

crc:=crc xor AByte; //将数据与CRC寄存器的低8位进行异或

for j:=0 to 7 do //对每一位进行校验

begin

tmp:=crc and 1; //取出最低位

crc:=crc shr 1; //寄存器向右移一位

crc:=crc and $7FFF; //将最高位置0

if tmp=1 then //检测移出的位,如果为1,那么与多项式异或

crc:=crc xor GENP;

crc:=crc and $FFFF;

end;

end;

begin

crc:=$FFFF; //将余数设定为FFFF

for i:=AStart to AEnd do //对每一个字节进行校验

CalOneByte(AData[i]);

Result:=crc;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

Data:array[0..255] of Byte;

i,j,Count:Integer;

Res:Word;

szData:string;

begin

szData:=Form1.Edit2.Text; //读入欲校验的字符串

Count:=StrToInt(form1.Edit3.Text); //读入需要计算的字符串长度

i:=1;

j:=0;

for j:=0 to Count-1 do

begin

if (i mod 2)=0 then //每2个字符放入一个字节中

i:=i+1;

if i=Length(szData) then

exit;

Data[j]:=StrToInt('$'+copy(szData,i,2)); //取出字符并转换为16进制数

i:=i+1;

end;

Res:=CalCRC16(Data,Low(Data),Count-1);

form1.Edit1.Text:=IntToHex(Res,4);

end;

end.

谁能帮我看看 这段VB求CRC-16的代码为什么和下面的C语言所求的CRC不一致。

把c的做成dll直接调用不就行了

Function CRC16_0(data() As Byte) As Long

Dim p1 As Long

Dim datalen As Long

datalen=UBound(data)

p1=VarPtr(data(1))

CRC16_0= cal_crc(p1,datalen)

End Function

crc16校验代码中 多项式码明明是8005 为什么要用A001来异或,还有CRC16-REV=A001是什么意思

0x8005=1000 0000 0000 0101B

0xA001=1010 0000 0000 0001B

对比两个二进制高低位正好是完全相反的,CRC校验分为正向校验与反向校验。正向校验高位在左,反向校验低位在左,比如正向CRC校验的数据为0xAF5D=1010 1111 0101 1101B与0x8005异或时应该是0xAF5D^0x8005,而要使用0xA001与数据进行校验也应该使0xAF5D高低位换顺序为0xBAF5=1011 1010 1111 0101B。正向校验使用左移位,反向校验使用右移位,其实原理是一样的,得看校验的数据高低位顺序。

crc16 c代码

0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,

0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,

0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,

0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,

0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,

0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,

0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,

0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,

0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,

0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,

0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,

0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,

0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,

0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,

0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,

0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,

0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,

0x40

};

static unsigned char auchCRCHi[]=

{

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,

0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,

0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,

0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,

0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,

0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,

0x40

};

bool CRCDecToHex(unsigned char Destination[],unsigned char Source,const int DesLen,int HexBit);

void UCToASCII(unsigned char Lo16[],int len);

unsigned short CRC16(unsigned char puchmsg[],unsigned short usdatalen);

int main()

{

//unsigned char buf[]={0x01,0xA8,0x98,0x42,0x65,0x74,0x74,0x65,0x72,0x17};

//unsigned char buf[]={0x07,0x11,0x41,0x00,0x53,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03};

unsigned char buf[]={0x00,0x00,0x01,0x00,0x00,0x00,0x1A,0x00,0x1C,0x03};

//unsigned short Len=10;

//unsigned short Len=19;

unsigned short Len=10;

unsigned char Lo=CRC16(buf,Len)%256;

unsigned char Hi=CRC16(buf,Len)/256;

unsigned char Lo16[4]={0};

unsigned char Hi16[4]={0};

printf(" 十进制:低字节Lo=%d\n 十进制:高字节Hi=%d\n",Lo,Hi);

unsigned char temp=Lo;

int ASCIILoLen=0;

CRCDecToHex(Lo16,temp,4,ASCIILoLen);

UCToASCII(Lo16,ASCIILoLen);

printf(" 低字节:Lo16=");

for (int i=0;iASCIILoLen;i++)

printf("%c",Lo16[i]);

printf("H\n");

temp=Hi;

int ASCIIHiLen=0;

CRCDecToHex(Hi16,temp,4,ASCIIHiLen);

UCToASCII(Hi16,ASCIIHiLen);

printf(" 高字节:Hi16=");

for (int I=0;IASCIIHiLen;I++)

printf("%c",Hi16[I]);

printf("H\n");

return 1;

}

//十进制转十六进制

bool CRCDecToHex(unsigned char Destination[],unsigned char Source,const int DesLen,int HexBit)

{

unsigned char temp=Source;

int i=DesLen-1;

while(temp=16)

{

Destination[i]=temp%16;

printf("Lo[%d]=%d\n",i,Destination[i]);

temp=temp/16;

i--;

}

Destination[i]=temp;

printf("Lo[%d]=%d\n",i,Destination[i]);

HexBit=DesLen-1-i+1;

for(int a=i;(a-i)(DesLen-1-i+1);a++)

{

Destination[a-i]=Destination[a];

printf("移位后:Lo16[%d]=%d\n",a-i,Destination[a-i]);

}

return true;

}

//无符号字符型转ASCII码

void UCToASCII(unsigned char Lo16[],int len)

{

for(int i=0;ilen;i++)

{

if (Lo16[i]=10)

{

switch (Lo16[i])

{

case 10:

Lo16[i]='A';break;

case 11:

Lo16[i]='B';break;

case 12:

Lo16[i]='C';break;

case 13:

Lo16[i]='D';break;

case 14:

Lo16[i]='E';break;

case 15:

Lo16[i]='F';break;

default: break;

}

}

else

{

Lo16[i]+=48;

}

}

}

unsigned short CRC16(unsigned char puchmsg[],unsigned short usdatalen)

{

unsigned char uchCRCHi=0xFF;

unsigned char uchCRCLo=0xFF;

unsigned short uIndex;

unsigned short y=0;

while(usdatalen--)

{

uIndex=uchCRCHi=(unsigned char)(uchCRCHi ^ puchmsg[y++]);

uchCRCHi=(unsigned char)(uchCRCLo ^ auchCRCHi[uIndex]);

uchCRCLo=auchCRCLo[uIndex];

}

return(unsigned short)(uchCRCLo+uchCRCHi*256);

求把这段C语言的CRC16校验代码转换成C#代码

static void Main(string[] args)

        {

            int i = CRC16("2200000C20140730111000000038465E4DA6F447D4992B0ABDD343CC110C02000105000703102015073000000000", "2200000C20140730111000000038465E4DA6F447D4992B0ABDD343CC110C02000105000703102015073000000000".Length);

            Console.Write(i.ToString("x"));

            Console.Read();

        }

        static int CRC16(string p, int len)

        {

            int l, h, t;

            int i;

            l = h = 0xff;

            for (i = 0; i  len; i++)

            {

                h ^= p[i];

                h ^= h  4;

                t = h;

                h = l;

                l = t;

                t = (l  4) | (l  4);

                h ^= ((t  2) | (t  6))  0x1f;

                h ^= t  0xf0;

                l ^= ((t  1) | (t  7))  0xe0;

            }

            i = ((int)h  8) | l;

            return i;

        }

关于crc16代码和crc 代码的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/18690.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载