unit Main
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls
type
TForm1 = class(TForm)
Memo1: TMemo
Label1: TLabel
Label2: TLabel
Label3: TLabel
GenPoly8Edit: TEdit
GenPoly16Edit: TEdit
GenPoly32Edit: TEdit
TestCRC8Btn: TButton
TestCRC16Btn: TButton
TestCRC32Btn: TButton
CalCRC8Btn: TButton
CalCRC16Btn: TButton
CalCRC32Btn: TButton
CRC8ResultEdit: TEdit
CRC16ResultEdit: TEdit
CRC32ResultEdit: TEdit
procedure FormCreate(Sender: TObject)
procedure TestCRC16BtnClick(Sender: TObject)
procedure TestCRC8BtnClick(Sender: TObject)
procedure TestCRC32BtnClick(Sender: TObject)
procedure CalCRC16BtnClick(Sender: TObject)
procedure CalCRC8BtnClick(Sender: TObject)
procedure CalCRC32BtnClick(Sender: TObject)
private
public
end
var
Form1: TForm1
GenPoly32: DWord
GenPoly16: Word
GenPoly8: Byte
GenPoly4: Byte
CRC32Tab: array [0..255] of DWord
CRC16Tab: array [0..255] of Word
CRC8Tab : array [0..255] of Byte
implementation
{$R *.DFM}
function CalCRC16(data, crc, genpoly: Word): Word
var i: Integer
begin
crc := crc xor (data shl 8)
for i:=0 to 7 do
if (crc and $8000) <>0 then
crc := (crc shl 1) xor genpoly
else crc := crc shl 1
Result := crc
end
procedure InitCRC16Tab(genpoly: DWord)
var i: Integer
begin
for i:=0 to 255 do
CRC16Tab[i] := CalCRC16(i,0,genpoly)
end
function QuickCRC16(data, crc: Word): Word
begin
crc := CRC16Tab[(crc shr 8) xor data] xor (crc shl 8)
Result := crc
end
function CalCRC8(data, crc, genpoly: Byte): Byte
var i: Integer
begin
crc := crc xor data
for i:=0 to 7 do
if (crc and $01) <>0 then
crc := (crc shr 1) xor genpoly
else crc := crc shr 1
Result := crc
end
procedure InitCRC8Tab(genpoly: DWord)
var i: Integer
begin
for i:=0 to 255 do
CRC8Tab[i] := CalCRC8(i,0,genpoly)
end
function QuickCRC8(data, crc: Byte): Word
begin
crc := CRC8Tab[crc xor data]
Result := crc
end
function CalCRC32(data, crc, genpoly: DWord): DWord
var i: Integer
begin
crc := crc xor data
for i:=0 to 7 do
if (crc and $01) <>0 then
crc := (crc shr 1) xor genpoly
else crc := crc shr 1
Result := crc
end
procedure InitCRC32Tab(genpoly: DWord)
var i: Integer
begin
for i:=0 to 255 do
CRC32Tab[i] := CalCRC32(i,0,genpoly)
end
function QuickCRC32(data, crc: DWord): DWord
begin
crc := CRC32Tab[Byte(crc xor data)] xor (crc shr 8)
Result := crc
end
procedure TForm1.FormCreate(Sender: TObject)
begin
GenPoly8 := StrToInt(GenPoly8Edit.Text)
InitCRC8Tab(GenPoly8)
GenPoly16 := StrToInt(GenPoly16Edit.Text)
InitCRC16Tab(GenPoly16)
GenPoly32 := StrToInt(GenPoly32Edit.Text)
InitCRC32Tab(GenPoly32)
end
procedure TForm1.TestCRC16BtnClick(Sender: TObject)
var data, crc, crcstart: Word
begin
crcstart := $1234
Memo1.Clear
Memo1.Lines.Add('16bit CRC')
for data:=0 to 255 do
begin
crc := CalCRC16(data,crcstart,GenPoly16)
Memo1.Text := Memo1.Text + IntToHex(crc, 4) + ' '
end
Memo1.Lines.Add('')
Memo1.Lines.Add('16bit Quick CRC')
for data:=0 to 255 do
begin
crc := QuickCRC16(data,crcstart)
Memo1.Text := Memo1.Text + IntToHex(crc, 4) + ' '
end
end
procedure TForm1.TestCRC8BtnClick(Sender: TObject)
var data, crc, crcstart: Byte
begin
crcstart := $12
Memo1.Clear
Memo1.Lines.Add('8bit CRC')
for data:=0 to 255 do
begin
crc := CalCRC8(data,crcstart,GenPoly8)
Memo1.Text := Memo1.Text + IntToHex(crc, 2) + ' '
end
Memo1.Lines.Add('')
Memo1.Lines.Add('8bit Quick CRC')
for data:=0 to 255 do
begin
crc := QuickCRC8(data,crcstart)
Memo1.Text := Memo1.Text + IntToHex(crc, 2) + ' '
end
end
procedure TForm1.TestCRC32BtnClick(Sender: TObject)
var data, crc, crcstart: DWord
begin
crcstart := $12345678
Memo1.Clear
Memo1.Lines.Add('32bit CRC')
for data:=0 to 255 do
begin
crc := CalCRC32(data,crcstart,GenPoly32)
Memo1.Text := Memo1.Text + IntToHex(crc, 8) + ' '
end
Memo1.Lines.Add('')
Memo1.Lines.Add('32bit Quick CRC')
for data:=0 to 255 do
begin
crc := QuickCRC32(data,crcstart)
Memo1.Text := Memo1.Text + IntToHex(crc, 8) + ' '
end
end
function GetDataFromText(str: String): String
var i, p1, p2: Integer
begin
Result := ''
while str <>'' do
begin
i := 0
p1 := Pos(' ',str)
p2 := Pos(#13#10,str)
if p1=1 then
begin Delete(str,1,1)continueend
if p2=1 then
begin Delete(str,1,2)continueend
if (p1=0) and (p2=0) and (str<>'') then
begin
i := StrToIntDef('$'+str,0)
Delete(str,1,Length(str))
end
if ((p1>0) and (p2=0)) or
((p1>0) and (p2>0) and (p1<p2)) then
begin
i := StrToIntDef('$'+Copy(str,1,p1-1),0)
Delete(str,1,p1)
end
if ((p1=0) and (p2>0)) or
((p1>0) and (p2>0) and (p1>p2)) then
begin
i := StrToIntDef('$'+Copy(str,1,p2-1),0)
Delete(str,1,p2+1)
end
Result := Result + Chr(i)
end
end
procedure TForm1.CalCRC16BtnClick(Sender: TObject)
var
i: Integer
databuf: String
data, crc: Word
begin
databuf := GetDataFromText(Memo1.Text)
crc := 0
for i:=1 to Length(databuf) do
begin
data := Ord(databuf[i])
crc := CalCRC16(data,crc,GenPoly16)
end
CRC16ResultEdit.Text := 'CRC16 = ' + IntToHex(crc,4)
end
procedure TForm1.CalCRC8BtnClick(Sender: TObject)
var
i: Integer
databuf: String
data, crc: Byte
begin
databuf := GetDataFromText(Memo1.Text)
crc := 0
for i:=1 to Length(databuf) do
begin
data := Ord(databuf[i])
crc := CalCRC8(data,crc,GenPoly8)
end
CRC8ResultEdit.Text := 'CRC8 = ' + IntToHex(crc,2)
end
procedure TForm1.CalCRC32BtnClick(Sender: TObject)
var
i: Integer
databuf: String
data, crc: DWord
begin
databuf := GetDataFromText(Memo1.Text)
crc := 0
for i:=1 to Length(databuf) do
begin
data := Ord(databuf[i])
crc := CalCRC32(data,crc,GenPoly32)
end
CRC32ResultEdit.Text := 'CRC32 = ' + IntToHex(crc,8)
end
end.
#include <stdio.h>typedef unsigned short ushort
typedef unsigned char uchar
typedef union _CRC
{
ushort crc16
uchar by[2]
} CRC
//输入不带CRC码的数据时,返回值是CRC码
//输入带CRC码的数据时,则可以进行校验,返回0时CRC校验成功,否则CRC校验失败
ushort CRC16(uchar *ba, int size)
{
CRC crc
crc.crc16 = 0xffff
int i, l
for (i=0i<sizei++)
{
uchar ch = ba[i]
crc.by[0] = crc.by[0] ^ ch
for (l=0l<8l++)
{
if (crc.by[0] &0x01)
{
crc.crc16 = crc.crc16 >>1
crc.crc16 = crc.crc16 ^ 0xa001
}
else
{
crc.crc16 = crc.crc16 >>1
}
}
}
uchar swap = crc.by[0]
crc.by[0] = crc.by[1]
crc.by[1] = swap
return crc.crc16
}
void main()
{
uchar ba[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
CRC crc
//计算CRC码
crc.crc16 = CRC16(ba, 8)
printf("高字节:0x%x, 低字节:0x%x\n", crc.by[1], crc.by[0])
//CRC校验
uchar bb[10] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xb0, 0xcf}
if (0 == CRC16(bb, 10))
{
printf("bb 校验成功!")
}
else
{
printf("bb 校验失败!")
}
}
下面我们以crc-16为例来说明任意长度数据流的crc校验码生成过程。我们采用将数据流分成若干个8bit字符,并由低字节到高字节传送的并行方法来求crc校验码。具体计算过程为:用一个16bit的寄存器来存放crc校验值,且设定其初值为0x0000;将数据流的第一个8bit与16bit的crc寄存器的高字节相异或,并将结果存入crc寄存器高字节;crc寄存器左移一位,最低1bit补零,同时检查移出的最高1bit,若移出的最高1bit为0,则继续按上述过程左移,若最高1bit为1,则将crc寄存器中的值与生成多项式码相异或,结果存入crc寄存器值;继续左移并重复上述处理方法,直到将8bit数据处理完为止,则此时crc寄存器中的值就是第一个8bit数据对应的crc校验码;然后将此时crc寄存器的值作为初值,用同样的处理方法重复上述步骤来处理下一个8bit数据流,直到将所有的8bit字符都处理完后,此刻crc寄存器中的值即为整个数据流对应的crc校验码。下面示出了其计算过程的流程图:
在用c语言编写crc校验码的实现程序时我们应该注意,生成多项式
对应的十六进制数为0x18005,由于crc寄存器左移过程中,移出的最高位为1时与
相异或,所以与16bit的crc寄存器对应的生成多项式的十六进制数可用0x8005表示。下面给出并行处理8bit数据流的c源程序:
unsigned
short
crc_dsp(unsigned
short
reg,
unsigned
char
data_crc)
//reg为crc寄存器,
data_crc为将要处理的8bit数据流
{
unsigned
short
msb
//crc寄存器将移出的最高1bit
unsigned
short
data
unsigned
short
gx
=
0x8005,
i
=
0
//i为左移次数,
gx为生成多项式
data
=
(unsigned
short)data_crc
data
=
data
<<
8
reg
=
reg
^
data
do
{
msb
=
reg
&
0x8000
reg
=
reg
<<
1
if(msb
==
0x8000)
{
reg
=
reg
^
gx
}
i++
}
while(i
<
8)
return
(reg)
}
以上为处理每一个8bit数据流的子程序,在计算整个数据流的crc校验码时,我们只需将crc_reg的初值置为0x0000,求第一个8bit的crc值,之后,即可将上次求得的crc值和本次将要处理的8bit数据作为函数实参传递给上述子程序的形参进行处理即可,最终返回的reg值便是我们所想得到的整个数据流的crc校验值。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)