什么是crc.?他有什么优缺点?

public static final String URL = "";

一、循环冗余码校验英文名称为Cyclical Redundancy

crc16在线_crc16在线计算crc16在线_crc16在线计算


crc16在线_crc16在线计算


crc16在线_crc16在线计算


criteria.add(Restrictions.le(MORE, Integer.parseInt(more.replace("<", ""))));

Check,简称CRC。它是利用除法及余数的原理来作错误侦测(Error

Detecting)的。实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CRC值不同,则说明数据通讯出现错误。

根据应用环境与习惯的不同,CRC又可分为以下几种标准:

①CRC-12码;

②CRC-16码;

③CRC-CCITT码;

④CRC-32码。

CRC-12码通常用来传送6-bit字符串。CRC-16及CRC-CCITT码则用是来传送8-bit字符,其中CRC-16为美国采用,而CRC-CCITT为欧洲所采用。CRC-32码大都被采用在一种称为Point-to-Point的同步传输中。

下面以常用的CRC-16为例来说明0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,其生成过程。

CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在位(MSB)的位置补零,而位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果LSB为零,则无需进行异或。重复上述的由高至低的移位8次,个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后CRC寄存器内的值即为终的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校验计算方法

}程序优化策略:上面程序都只是给出了通用算法,并没有考虑到51单片机的特点。我们知道,51单片机是8位单片机,使用的变量类型也是8位的。如果在程序中使用8位的变量速度是快的,比使用16位的变量代码短、效率高。在上面的程序中都使用了大量整型数类型(16位)的表格和整型数类型的变量,特别是关键的变量。如果我们不使用整型类型的表格和变量,而使用字节类型的表格和变量,就能够使程序的性能得到优化。基于这种思路,我们将原来整型的表格拆分为两个字节型(8位)的表格,即将原来表格的高低字节分别拆开,每个表格还是256个单元,这样表格的大小和顺序都没有变;原来使用16位变量计算的地方,改用8位变量计算。

你}}这个是CRC16

CRC校验,你首先要把信息看成是比特流,就是由位(bit)组成的信息,而不要有字节的概念,1~16共计有16字节吧也就是168共计128个bit,也就是信息码长度为k=128,R=16,

要实现校验的话,你首先需要知道对方采用的是何种CRC公式

不同的CRC公式 得到的校验码是不一样的

在知道公式的情况下

做crc表,然后按照crc算法,计算这8个字节的整体crc

如果传输没有错误的话,终的crc值是0

也可以计算前六个的crc,然后和两个字节比较,效果是相同的。

用ja编写一个获得CRC校验码的jabean

JobAll entities. Transaction control of the se(), update() and delete()

CRC16 crc16 = new CRC10x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,6();

8. 注意C51的特点,按照C51的特点编写程序;

byte[] b = str.getBytes();

for (int i = 0; i < b.length; i++)

crc16.update(b[i]);

return Integer.toHexString(crc16.value);

}private static String mkCrc(String string) throws Exception {

CRC32 crc32 = new CRC32();

crc32.update(string.getBytes());

return Long.toHexString(crc32.getValue());

}public class CRCUtil {

public static final int evalCRC16(byte[] data) {

int crc = 0xFFFF;

for (int i = 0; i < data.length; i++) {

crc = (data[i] << 8) ^ crc;

for (int j = 0; j < 8; ++j)

if ((crc & 0x8000) != 0)

crc = (crc << 1) ^ 0x1021;

else

crc <<= 1;

}return (crc ^ 0xFFFF) & 0xFFFF;

public class CRC16 {

public static String getData(String data){

byte[] b=data.getBytes();

short crc=0;

for(int n=0;n

for (char i = 0x80; i != 0; i >>= 1)

{if ((crc&0x8000) != 0)

crc ^= 0x1021;

}else

}if ((b[n]&i) != 0)

{crc ^= 0x1021;

}return Integer.toHexString(crc & 0xFFFF);

}public static void main(String[] args) {

System.out.println(CRC16.getData("1234567890"));

crc 16 delphi 算法!

package cn.tomcat7.dao;

为什么不在网上找一下呢?CRC一般常用的有查表法。以前我做一个串口传输入程序的时候,就是在网上找的源代码。然后自己稍稍改了一下就OK了。

iIndex

如果是用计算法的话,说老实话,我也不太明白。呵呵。不过真正应用if(!area.equals("All")){的时候,重要的是结果。

求助大神还有哪些16位冗余校验计算方法,试过常见的几种CRC16都不对

CRC校验又称为循环冗余校验,是数据通讯中常用的一种校验算法。它可以有效的判别出数据在传输过程中是否发生了错误,从而保障了传输的数据可靠性。

CRC校验有多种方式,如:CRC8、CRC16、CRC32等等。在实际使用中,我们经常使用CRC16校验。CRC16校验也有多种,如:1005多项式、1021多项式(CRC-ITU)等。在这里我们不讨论CRC算法是怎样产生的,而是重点落在几种算法的C51程序的优化上。

计算CRC校验时,常用的计算方式有三种:查表、计算、查表+计算。一般来说,查表法快,但是需要较大的空间存放表格;计算法慢,但是代码简洁、占用空间小;而在既要求速度,空间又比较紧张时常用查表+计算法。

下面我们分别就这三种方法进行讨论和比较。这里以使用广泛的51单片机为例,分别用查表、计算、查表+计算三种方法计算

1021多项式(CRC-ITU)校验。原始程序都是在网上或杂志上经常能见到的,相信大家也比较熟悉了,甚至就是正在使用或已经使用过的程序。

编译平台采用 Keil C51 7.0,使用小内存模式,编译器默认的优化方式。

常用的查表法程序如下,这是网上经常能够看到的程序范例。因为篇幅关系,省略了大部分表格的内容。

code unsigned int Crc1021Table[256] = {

0x0000, 0x1021, 0x2042, 0x3063,... 0x1ef0

};

unsigned int crc0(unsigned char pData, unsigned char nLength)

{unsigned int CRC16 = 0;

while(nLength>0)

{CRC16 = (CRC16 << 8 ) ^ Crc1021Table[((CRC16>>8) ^ pData) & 0xFF];

nLength--;

pData++;

}return CRC16;

}编译后,函数crc0的代码为68字节,加上表格占用的512字节,一共使用了580个字节的代码空间。

下面是常见的计算法的程序:

unsigned int crc2(unsigned char ptr,unsigned char count)

{unsigned int crc =0;

unsigned char i;

while(count-- >0)

{crc = ( crc^(((unsigned int)ptr)<<8));

for(i=0;i<8;i++)

{if(crc&0x8000) crc= ((crc<<1)^0x1021);

else crc <<= 1;

}ptr++;

}return crc;

}下面是常见的一种查表+计算的方法:

unsigned int crc4(unsigned char ptr, unsigned char len) {

unsigned int crc;

unsigned char da;

code unsigned int crc_ta[16]={ / CRC余式表 /

0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,

0x8108,0x29,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,

};

crc=0;

while(len-->0) {

da = ((crc/256))/16; / 暂存CRC的高四位 /

/ CRC右移4位,相当于取CRC的低12位)/

crc ^= crc_ta[da^(ptr/16)];

/ CRC的高4位和本字节的前半字节相加后查表/

/计算CRC,然后加上上一次CRC的余数 /

da = ((crc/256))/16; / 暂存CRC的高4位 /

/ CRC右移4位, 相当于CRC的低12位) /

crc ^= crc_ta[da^(ptr&0x0f)];/ CRC的高4位和本字节的后半字节相加后查表/

/计算CRC,然后再加上上一次CRC的余数 /

ptr++;

}return crc;

修改后的查表程序如下(省略了表格的内容):

code unsigned char crctableh[256]={

0x00,0x10,0x20,0x30,... 0x0E,0x1E,

};

code unsigne68+512=580d char crctablel[256]={

0x00,0x21,0x42,0x63,... 0xD1,0xF0,

};

unsigned int crc1(unsigned char buf,unsigned char n)

{unsigned char t;

unsigned char c[2];

unsigned int x;

}data crc;

while(n !=0)

{t = crc.c[0]^buf;

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个字节。这两个函数的运行对比情况见表一。

我们采用和上面相同的优化方法来优化计算法的程序,优化后的计算法程序为:

unsigned int crc3(unsigned char ptr,unsigned char count)

{data unsigned char i;

unsigned char c[2];

unsigned int x;

}data crc;

crc.x=0;

while(count!=0)

{crc.c[0] ^= ptr;

for(i=8;i>0;i--)

{if(crc.c[0]&0x70)crc.x=(crc.x<<1)&0x1021;

else crc.x=crc.x<<1;

}ptr++;

count--;

}return crc.x;

}编译后函数crc2的代码长度为76,函数crc3的代码长度为68,变化不是太大,但是执行效率是很不一样的,具体别见后面的表一。

优化后的查表+计算法的程序为:

unsigned int crc5(unsigned char ptr,unsigned char len)

{code unsigned char crch[16]={ / CRC余式表 /

0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,

0x81,0x,0xa1,0xb1,0xc1,0xd1,0xe1,0xf1,

};

code unsigned char crcl[16]={ / CRC余式表 /

0x00,0x21,0x42,0x63,0x84,0xa5,0xc6,0xe7,

0x08,0x29,0x4a,0x6b,0x8c,0xad,0xce,0xef,

};

unsigned char c[2];

unsigned int x;

}data crc;

unsigned char t;

crc.x =0;

while(len!=0) {

crc.x <<=4;

crc.c[0] ^=crch[t];

crc.c[1] ^=crcl[t];

t = (crc.c[0]>>4) ^ (ptr & 0x0F);

crc.x <<=4;

crc.c[0] ^=crch[t];

crc.c[1] ^=crcl[t];

ptr++;

len--;

}return crc.x;

}优化前后的代码长度分别为175字节和146字节(包括了32字节的表格空间)。

代码测试:仅代码长度变短是不够的,衡量优化后的程序一个重要的标准是看优化前后两个函数执行相同的计算量使用的时间,或者说执行的效率是否提高了。如果优化后的函数需要时间少,就说明我们优化后的函数确实提高了效率,否则就是反而降低了程序的效率,优化失败。我在 Keil C51 下编写了一个测试程序,在程序中调用了上面的六个函数,共同计算一个长度为200字节的CRC校验,并记录下每个函数使用的时间。测试方法为:使用 Keil C51 的软件仿真功能(采用带计时功能的硬件仿真器也可以),在每个函数上加上断点,记录下执行到每个断点的时间,然后前后相减就得出每个函数的执行时间。仿真时使用的单片机型号为AT89C51,晶体频率为12MHz。

测试文件的源代码为:

xdata unsigned char buf[200];

unsigned char i;

unsigned int crc;

extern unsigned int crc0(unsigned char ,unsigned char);

extern unsigned int crc1(unsigned char ,unsigned char);

extern unsigned int crc2(unsigned char ,unsigned char);

extern unsigned int crc3(unsigned char ,unsigned char);

extern unsigned int crc4(unsigned char ,unsigned char);

extern unsigned int crc5(unsigned char ,unsigned char);

void main(void)24229

buf[i]=i+1;

crc=crc0(buf,200);

crc=crc1(buf,200);

crc=crc2(buf,200);

crc=crc3(buf,200);

crc=crc4(buf,200);

crc=crc5(buf,200);

i=0;

}测试结果见表一:

函数

代码长度(字节)

执行时间(微秒)

提高效率

查表法

Crc0

10626

28%

Crc1

44+512=556

7622

计算法

Crc2

76

30309

13.6%

Crc3

68

26186

查表+计算

Crc4

18.2%

Crc5

146

19822

表一:三种CRC16校验算法及其优化的比较

从表中可以看出,优化后的函数执行速度都有了明显的提高,这说明我们的优化是很有效的。其实优化前后的函数区别并不大,算法都是完全一样的,只是个别地方的写法调整了一下,但是取得的效果是非常明显的。现在很多人写单片机的程序,都带有写VC或C++的习惯,而没有考虑到51单片机的特点,从而造成了一些资源的浪费。

这三种计算方法之间的对比也很清楚,查表法使用的时间短,查表+计算次之,计算法长,它们的执行效率比为1:3.4:2.6,代码效率比为8.1:1:2.1(优化后的函数)。从代码长度看,查表法因为使用了一个相对较大的表格,所以代码长,适合于代码空间比较充足的情况;计算法没有使用任何表格,所以代码长度小,适合于ROM空间比较小的情况。而查表+计算法从执行速度和代码长度都是处于中流,是一种很好的折衷方案。

下面是我总结的一些C51编程优化的几个小技巧和方法:

1. 尽量使用无符号的变量;

3. 使用小的变量类型,能使用整型时就不要使用长整型,能使用字符型时就不要使用整型;

4. 多使用局部变量,少使用全局变量、静态变量,这样可以充分利用Keil提供的变量覆盖技术。同时局部变量也要尽量使用寄存器变量;

5. 少使用浮点数。使用浮点数需要连接浮点库,会增加大约1K的代码;而且浮点运算的速度是很慢的,没有特殊情况尽量使用定点数代替浮点数;

7. 函数带有的参数不要太多,多了会影响效率;

9. 多用几种方法优化,比较后找出方法;

10. 注意软件的写法,有时一个写法上很小的变化就会有意想不到的效果。因为Keil的优化是与上下文的程序相关的,对于不同的情况产生不同的优化。如果对比一下产生的汇编代码,就能够更加容易的找出不合理的代码,从而有针对性的优化了;

11. 不要过于依赖C51提供的优化功能,能够自己优化的地方就自己手工优化了,程序不可能完成所有的事情;

12. 不同版本的C51(特别是6.0和7.0的版本与低于6.0的版本相比)产生的优化效果可能会不同,产生的代码会不完全一样,需要特别注意;

13. 在循环中比较条件尽量与0作比较(这与51单片机的特点有关,对比一下编译产生的汇编代码就明白了),这样可以减少代码,加快速度。如:

将while( n > 10 )修改为

while( n != 0 );

14. 在循环中比较中不要直接使用 n-- 或 n++ ,而要分开写,这样产生的代码较小。

如:while( n-- != 0)修改为

while(n != 0)

{n--;

...//其他代码

}15. 尽量不要使用太复杂的表达式,虽然这样程序简洁,但是对程序的调试不方便。

只要能充分考虑到所使用的单片机的特点,在加上一些经验和技巧,就一定可以编写出高性能的程序来。

Modbus的Crc校验有几种 常用的有16位CRC和32位CRC

{crc criteria.add(Restrictions.ge({for(i=0;i<200;i++)MORE, Integer.parseInt(more.replace(">", ""))));<<= 1;

Modbus一般采用CRC16校验,特征多项式取0xA001。你可以用标准的CRC16算法代码,不过要更改特征多项式。所以一般大家都是用查表法处理Modbus的CRC校验部分的,反正也就512个字节。具体的代码你上网搜索“Modbus CRC16”,一抓一大把,我在这里就不...

VB CRC校验问题

crc <<=4;

大概看了下。有变量定义类型错误,修改如下:

0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,

Public

Function

crc16(ByRef

cmdstring()

}if(!branch.equals("All")){As

Byte,

DataLen

As

Integer)

As

String

Dim

data

As

Integer

Dim

iAs

Integer

Dim

CRCHi

As

long,

CRCLo

As

long'这里应该定义为long.因为下面赋值是long型。朋友。

Dim

As

Long

Dim

CRCStr

As

String

Dim

DataStr

As

String

CRCLo

=&HFF'看这里的赋值。long型

CRCHi

=&HFF

For

i=

To

DataLen

=CRCLo

Xor

cmdstring(i)

CRCLo

=CRCHi

Xor

GetCRCLo(iIndex)

'低位处理

CRCHi

=GetCRCHi(iIndex)

'高位处理

DataStr

=DataStr

&Chr(cmdstring(i))

Next

iDim

ReturnData(1)

As

Byte

ReturnData(1)

=CRCHi

ReturnData(0)

=CRCLo

CRCStr

=StrConv(ReturnData,

vbUnicode)

crc16

=DataStr

+CRCStr

End

Function

已知CRC-16校验码的生成多项式求用Matlab编程输出结果位CRC校验码表输出结果如图

import cn.tomcat7.HibernateSessionFactory;

import cn.tomcat7.bean.JobAll;

import ja.util.ArrayList;

import ja.util.List;

import org.hibernate.Criteria;

import org.hibernate.Session;

import org.hibernate.criterion.Restrictions;

/

A data access object (DAO) providing persistence and search support for

operations can directly support Spring container-mad transactions or they

can be augmented to handle user-mad Spring transactions. Each of these

mods provides additional rmation for how to configure it for the

desired type of transaction control.

@see cn.tomcat7.bean.JobAll

@author MyEclipse Persistence Tools

/

public 处理。仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。class JobAllDAO extends BaseHibernateDAO {

public static final String TITLE = "title";

public static final String KIND = "kind";

public static final String BRANCH = "branch";

public static final String MORE = "more";

private Session session = null;

public JobAll findById(ja.lang.Integer id) {

session = HibernateSessionFactory.getSession();

JobAll job = new JobAll();

try {

session.beginTransaction();

job = (JobAll) getSession().get("cn.tomcat7.bean.JobAll", id);

} catch (RuntimeException re) {

re.printStackTraceprivate static String mkCrc16(String str) {();

}return job;

}@SuppressWarnings("unchecked")

public List findAll(String kind, String area, String branch, String more) {

session = HibernateSessionFactory.getSession();

List list = new ArrayList();

try {

session.beginTransaction();

Criteria criteria = session.createCriteria(JobAll.class);

criteria.add(Restrictions.eq(KIND, kind));

//其他约束条件

criteria.add(Restrictions.eq(AREA, area));

criteria.add(Restrictions.eq(BRANCH, branch));

}if(!more.equals("All")){

if(more.contains("~")){

String strings[] = more.split("~");

criteria.add(Restrictions.ge(MORE, Integer.parseInt(strings[0])))

.add(Restrictions.le(MORE, Integer.parseInt(strings[1])));

}else if(more.contains(">")){

}else if(more.contains("<")){

list = criteria.list();

} catch (RuntimeException re) {

re.printStackTrace();

}return lp1=VarPtr(data(1))ist;

}public JobAll merge(JobAll detachedInstance) {

JobAll job = new JobAll();

session = HibernateSessionFactory.getSession();

try {

session.beginTransaction();

job = (JobAll) getSession().merge(detachedInstance);

} catch (RuntimeException re) {

re.printStackTrace();

}return job;

CRC检查(16位),

t = (crc.c[0]>>4) 6. 没有必要就不要使用printf等标准输入输出函数,它会增加大约3K的代码。^ (ptrcrc.x = 0; >>4);

关于CRC校验66

175

CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行

2. 尽量使用data与idata寄存器变量;它们之间的效率顺序为data>idata>xdata ;

CRC产生过程中,每个8位字符都单独和寄存器内容相或(OR),结果向有效位方向移动,有效位以0

union{

填充。LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。整个过程要重

复8次。在一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。终寄存器中的值,是消息

中所有的字节都执行之后的CRC值。 CRC添加到消息中时,低字节先加入,然后高字节。

CRC简单函数如下:

unsigned short CRC16(puchMsg,usDataLen)

unsigned char puchMsg; / 要进行CRC校验的消息 /

{unsigned char uchCRCHi=0xFF; / 高CRC字节初始化 /

unsigned char uchCRCLo=0xFF; / 低CRC 字节初始化 /

unsigned uIndex; / CRC循环中的索引 /

while (usDataLen--) / 传输消息缓冲区 /

{uIndex=uchCRCHi^puchMsgg++; / 计算CRC /

uchCRCHi=uchCRCLo^auchCRCHi[uIndex];

uchCRCLo=auchCRCLo[uIndex];

}return (uchCRCHi<<8|uchCRCLo);

}/ CRC 高位字节值表 /

static unsigned char auchCRCHi[]={

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

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,

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

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

};

/ CRC低位字节值表/

static char auchCRCLo[]={

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,

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, 0x, 0x51, 0x93, 0x53, 0x52, 0x92,

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

};

好好看看吧不会连这么简单的C++语言都读不懂吧???wlr希望采纳我的

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

unsigned short usDataLen; / 消息中字节数 /

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

Function CRC16_0(data() As Byte) As Long

Dim p1 A// property constantss Long

Dim datalen As Long

datpublic static final String AREA = "area";alen=UBound(data)

CRC16_0= cal_crc(p1,datalen)

End Function