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 校验失败!")
}
}
我给你delphi的饥枣CRC算法,烂歼拆这个文改腊件可以直接使用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.
按位计算CRC采用CRC-CCITT多项式,多项式为0x11021,C语言编程时,参与计算为0x1021。当按位计算CRC时,例如计算二进制序列为1001 1010 1010 1111时,将二进制序列数左移16位,即为1001 1010 1010 1111 (0000 0000 0000 0000),实际上该二进制序列可拆分为1000 0000 0000 0000 (0000 0000 0000 0000) + 000 0000 0000 0000 (0000 0000 0000 0000) + 00 0000 0000 0000 (0000 0000 0000 0000) + 1 0000 0000 0000 (0000 0000 0000 0000) + ……现在开始分析运算:
<1>对第一个二进制分序列求余数,竖式除激肢法即为0x10000 ^ 0x11021运算,后面的0位保留;
<2>接着对第二个二进制分序列求余数,将第一步运算的余数*2后再和第二个二进制分序列一起对0x11021求余,这一步理解应该没什么问题。如果该分序列为0,无需计算。
<3>对其余的二进制序列求余与上面两步相同。
<4>计算到最后一位时即为整个二进制序列的余数,即为CRC校验码。
该计算岩衡方法相当于对每一位计算,运算过程很容易理解,所占内存少,缺点是一位一位计算粗铅做比较耗时。
下面给出C语言实现方法:
代码如下:
unsigned char test[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}
unsigned char len = 16
void main( void )
{
unsigned long temp = 0
unsigned int crc
unsigned char i
unsigned char *ptr = test
while( len-- ) {
for(i = 0x80i != 0i = i >>1) {
temp = temp * 2
if((temp &0x10000) != 0)
temp = temp ^ 0x11021
if((*ptr &i) != 0)
temp = temp ^ (0x10000 ^ 0x11021)
}
ptr++
}
crc = temp
printf("0x%x ",crc)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)