您的位置:程序门 -> vb -> 资源



vb下如何编写crc校验程序


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


vb下如何编写crc校验程序
发表于:2007-11-30 23:57:23 楼主
网络上找到的,先收藏到这里

vb下如何编写crc校验程序


  随着计算机技术的不断发展,在现代工业中,利用微机进行数据通讯的工业控制应用得也越来越广泛。由于传输距离、现场状况等诸多可能出现的因素影响,计算机与受控设备之间的通讯数据常会发生无法预测的错误。为了防止错误所带来的影响,一般在通讯时采取数据校验的办法,而循环冗余码校验是最常用的校验方法之一。


一、   循环冗余码校验原理


  循环冗余码校验英文名称为cyclical   redundancy   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为例来说明其生成过程。

  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校验码的产生过程,编写起程序来就非常容易了。由于visual   basic的广泛普及以及其在数据通讯中的重要地位,下面就以vb语言来编写crc的生成程序,其它语言只需稍做修改即可。

  编写crc校验程序有两种办法:一种为计算法,一种为查表法。下面对两种方法分别讨论。


  1.计算法

  计算法就是依据crc校验码的产生原理来设计程序。其优点是模块代码少,修改灵活,可移植性好。其缺点为计算量大。为了便于理解,这里假定了三位数据,而多项式码为a001(hex)。

  在窗体上放置一命令按钮command1,并添加如下代码:


  private   sub   command1_click()

   dim   crc()   as   byte

   dim   d()   as   byte   '待传输数据

   redim   d(2)   as   byte

   d(0)   =   123

   d(1)   =   112

   d(2)   =   135

   crc   =   crc16(d)   '调用crc16计算函数

   'crc(0)为高位

   'crc(1)为低位

  end   sub

  注意:在数据传输时crc的低位可能在前,而高位在后。


  function   crc16(data()   as   byte)   as   string

   dim   crc16lo   as   byte,   crc16hi   as   byte   'crc寄存器

   dim   cl   as   byte,   ch   as   byte        '多项式码&ha001

   dim   savehi   as   byte,   savelo   as   byte

   dim   i   as   integer

   dim   flag   as   integer

   crc16lo   =   &hff

   crc16hi   =   &hff

   cl   =   &h1

   ch   =   &ha0

   for   i   =   0   to   ubound(data)

    crc16lo   =   crc16lo   xor   data(i)   '每一个数据与crc寄存器进行异或

    for   flag   =   0   to   7

     savehi   =   crc16hi

     savelo   =   crc16lo

     crc16hi   =   crc16hi   \   2      '高位右移一位

     crc16lo   =   crc16lo   \   2      '低位右移一位

     if   ((savehi   and   &h1)   =   &h1)   then   '如果高位字节最后一位为1

      crc16lo   =   crc16lo   or   &h80   '则低位字节右移后前面补1

     end   if                '否则自动补0

     if   ((savelo   and   &h1)   =   &h1)   then   '如果lsb为1,则与多项式码进行异或

      crc16hi   =   crc16hi   xor   ch

      crc16lo   =   crc16lo   xor   cl

     end   if

    next   flag

   next   i

   dim   returndata(1)   as   byte

   returndata(0)   =   crc16hi       'crc高位

   returndata(1)   =   crc16lo       'crc低位

   crc16   =   returndata

  end   function


  2.查表法

  查表法的优缺点与计算法的正好相反。为了便于比较,这里所有的假定与计算法的完全相同,都而在窗体上放置一个command1的按钮,其代码部分与上面的也完全一致。下面只介绍crc函数的编写源代码。


  private   function   crc16(data()   as   byte)   as   string

   dim   crc16hi   as   byte

   dim   crc16lo   as   byte

   crc16hi   =   &hff

   crc16lo   =   &hff

   dim   i   as   integer

   dim   iindex   as   long

   for   i   =   0   to   ubound(data)

    iindex   =   crc16lo   xor   data(i)

    crc16lo   =   crc16hi   xor   getcrclo(iindex)    '低位处理

    crc16hi   =   getcrchi(iindex)          '高位处理

   next   i

   dim   returndata(1)   as   byte

   returndata(0)   =   crc16hi    'crc高位

   returndata(1)   =   crc16lo    'crc低位

   crc16   =   returndata

  end   function


  'crc低位字节值表

  function   getcrclo(ind   as   long)   as   byte

   getcrclo   =   choose(ind   +   1,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   _

&h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40,   &h1,   &hc0,   &h80,   &h41,   &h1,   &hc0,   &h80,   &h41,   &h0,   &hc1,   &h81,   &h40)

  end   function


  'crc高位字节值表

  function   getcrchi(ind   as   long)   as   byte

   getcrchi   =   choose(ind   +   1,   &h0,   &hc0,   &hc1,   &h1,   &hc3,   &h3,   &h2,   &hc2,   &hc6,   &h6,   &h7,   &hc7,   &h5,   &hc5,   &hc4,   &h4,   &hcc,   &hc,   &hd,   &hcd,   &hf,   &hcf,   &hce,   &he,   &ha,   &hca,   &hcb,   &hb,   &hc9,   &h9,   &h8,   &hc8,   &hd8,   &h18,   &h19,   &hd9,   &h1b,   &hdb,   &hda,   &h1a,   &h1e,   &hde,   &hdf,   &h1f,   &hdd,   &h1d,   &h1c,   &hdc,   &h14,   &hd4,   &hd5,   &h15,   &hd7,   &h17,   &h16,   &hd6,   &hd2,   &h12,   &h13,   &hd3,   &h11,   &hd1,   &hd0,   &h10,   &hf0,   &h30,   &h31,   &hf1,   &h33,   &hf3,   &hf2,   &h32,   &h36,   &hf6,   &hf7,   &h37,   &hf5,   &h35,   &h34,   &hf4,   &h3c,   &hfc,   &hfd,   &h3d,   &hff,   &h3f,   &h3e,   &hfe,   &hfa,   &h3a,   &h3b,   &hfb,   &h39,   &hf9,   &hf8,   &h38,   &h28,   &he8,   &he9,   &h29,   &heb,   &h2b,   &h2a,   &hea,   &hee,   &h2e,   &h2f,   &hef,   &h2d,   &hed,   &hec,   &h2c,   &he4,   &h24,   &h25,   &he5,   &h27,   &he7,   &he6,   &h26,   &h22,   &he2,   &he3,   &h23,   &he1,   &h21,   &h20,   &he0,   &ha0,   &h60,   _

&h61,   &ha1,   &h63,   &ha3,   &ha2,   &h62,   &h66,   &ha6,   &ha7,   &h67,   &ha5,   &h65,   &h64,   &ha4,   &h6c,   &hac,   &had,   &h6d,   &haf,   &h6f,   &h6e,   &hae,   &haa,   &h6a,   &h6b,   &hab,   &h69,   &ha9,   &ha8,   &h68,   &h78,   &hb8,   &hb9,   &h79,   &hbb,   &h7b,   &h7a,   &hba,   &hbe,   &h7e,   &h7f,   &hbf,   &h7d,   &hbd,   &hbc,   &h7c,   &hb4,   &h74,   &h75,   &hb5,   &h77,   &hb7,   &hb6,   &h76,   &h72,   &hb2,   &hb3,   &h73,   &hb1,   &h71,   &h70,   &hb0,   &h50,   &h90,   &h91,   &h51,   &h93,   &h53,   &h52,   &h92,   &h96,   &h56,   &h57,   &h97,   &h55,   &h95,   &h94,   &h54,   &h9c,   &h5c,   &h5d,   &h9d,   &h5f,   &h9f,   &h9e,   &h5e,   &h5a,   &h9a,   &h9b,   &h5b,   &h99,   &h59,   &h58,   &h98,   &h88,   &h48,   &h49,   &h89,   &h4b,   &h8b,   &h8a,   &h4a,   &h4e,   &h8e,   &h8f,   &h4f,   &h8d,   &h4d,   &h4c,   &h8c,   &h44,   &h84,   &h85,   &h45,   &h87,   &h47,   &h46,   &h86,   &h82,   &h42,   &h43,   &h83,   &h41,   &h81,   &h80,   &h40)

  end   function
发表于:2007-12-01 12:12:461楼 得分:0
顶一下.
发表于:2007-12-01 14:41:522楼 得分:0
是不是我太笨了,我还是没看懂~~

crc的目的,在于校验数据的完整性!
像楼主说的,发送端在一开始就把数据的crc计算出来,然后连同要发送的数据一起发送!

问题是,如果数据在传输过程中真的发生了变异,那么数据里面的原crc值难保它不会发生变异!
这样到接收端校验数据时,如果发送过来的crc值是错误的,那么也就计算错误了~~~

这怎么搞?
发表于:2007-12-10 20:49:283楼 得分:0
这个收藏办法值得借鉴。呵呵
发表于:2007-12-29 10:56:334楼 得分:0
你管他是数据体出错还是crc值出错,随便一个出错,crc校验都对不上,当然得作废
发表于:2007-12-29 19:44:185楼 得分:0
当一回收藏家!


快速检索

最新资讯
热门点击