300分求一CRC8算法,内容已经给出 大家快来抢分 正线等 ( 积分: 100 )

  • 主题发起人 主题发起人 wuchunhua
  • 开始时间 开始时间
W

wuchunhua

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,大体意思如下:
校验多项式为G(X)=X8+X2+X+1,对每个控制字或信息字的前5个字节进行CRC校验,生成一个8位的余数,该余数取反后即作为校验码尾随前5个字节发送.
计算方法如下:将每个字节的控制字或信息字中的前5个字节按从低到高的顺序排列,每个字节的位从高到低排列,构成一个位流,在这个位流的后面加上8个0,从而得到一个48位的位流。用校验多项式107H(X8+X2+X+1)作为除数去除这个码流,相除时不做减法而做异或,得到一个8位的余数,将这个余数取反后或到48位的码流尾部,既可得到一个带8为的CRC校验码的48位序列。
例:有信息字包括下面5个字节43H,E8H,7DH,33H,56H,可得到一个码流01000011,11101000,01111101,00110011,01010110,00000000,用107H除该码流,得到余数2FH,取反得到校验码D0H,最后发送的字节为:43H,E8H,7DH,33H,56H,DOH共6个字节.
 
如题,大体意思如下:
校验多项式为G(X)=X8+X2+X+1,对每个控制字或信息字的前5个字节进行CRC校验,生成一个8位的余数,该余数取反后即作为校验码尾随前5个字节发送.
计算方法如下:将每个字节的控制字或信息字中的前5个字节按从低到高的顺序排列,每个字节的位从高到低排列,构成一个位流,在这个位流的后面加上8个0,从而得到一个48位的位流。用校验多项式107H(X8+X2+X+1)作为除数去除这个码流,相除时不做减法而做异或,得到一个8位的余数,将这个余数取反后或到48位的码流尾部,既可得到一个带8为的CRC校验码的48位序列。
例:有信息字包括下面5个字节43H,E8H,7DH,33H,56H,可得到一个码流01000011,11101000,01111101,00110011,01010110,00000000,用107H除该码流,得到余数2FH,取反得到校验码D0H,最后发送的字节为:43H,E8H,7DH,33H,56H,DOH共6个字节.
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2380151


Function CalcCRC(S:String):Char;
Var
q,r,Crc:word;
B:byte;
begin
Crc:=Byte(S[1]);
B:=Byte(S[2]);
R:=0;
Q:=1;
CRC:=Crc shl 1;
while Q<6 do
begin
if ((b and ($80 shr r))<>0) then CRC:=CRC or 1;
if CRC>=$100 then CRC:=CRC xor $107;
CRC:=CRC shl 1;
Inc(R);
if r=8 then
begin
r:=0;
inc(q);
b:=Byte(S[Q+1]);
end;
end;
B:=CRC shr 1;
B:=not B;
result:=chr(B);
end;
 
我不是很明白,比如
我要得到
var
FBuf:array[1..5] of byte;
begin
FBuf[1]:=$43;
FBuf[2]:=$23;
FBuf[3]:=$56;
FBuf[4]:=$e4;
FBuf[5]:=$01;
请问我怎么调用你上面的程序得到上面5个字节的Crc校验值
end
 
1、把string 类型修改成array of byte是一样的,你可以看函数体
2、有个函数可以把byte的数组转成字符串数组,但是我没有测试过,建议用第一中方法
function ByteToStr(T: array of byte): string;
const
Digits: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');

var
I: integer;
begin
Result := '';
for I := Low(T) to High(T) do
Result := Result + Digits[(T shr 4) and $0f] + Digits[T and $0f];
end;

另外你可以把正确的结果发出来,大家帮你调一下,这个代码也是网上的

下面是我自己设置的一些代码,两种方式看看哪钟能满足你的要求
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, OleServer, Word2000, OleCtnrs;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function CalcCRC(s : array of byte): Char;overload;
function CalcCRC(s : string): Char;overload;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
FBuf:array[1..5] of byte;
strCRC: String;
strTemp : string;
function ByteToStr(T: array of byte): string;
const
Digits: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
var
I: integer;
begin
Result := '';
for I := Low(T) to High(T) do
Result := Result + Digits[(T shr 4) and $0f] + Digits[T and $0f];
end;
begin
FBuf[1]:=$43;
FBuf[2]:=$23;
FBuf[3]:=$56;
FBuf[4]:=$e4;
FBuf[5]:=$01;
strCRC := CalcCRC(fBuf);// 用array of byte的方式

strTemp:= ByteToStr(fBuf);// 用string的方式
strCRC := CalcCRC(strTemp);
end;

Function TForm1.CalcCRC(s : array of byte):Char;
Var
q,r,Crc:word;
B:byte;
begin
Crc:=Byte(S[1]);
B:=Byte(S[2]);
R:=0;
Q:=1;
CRC:=Crc shl 1;
while Q<6 do begin
if ((b and ($80 shr r))<>0) then CRC:=CRC or 1;
if CRC>=$100 then CRC:=CRC xor $107;
CRC:=CRC shl 1;
Inc(R);
if r=8 then begin
r:=0;
inc(q);
b:=Byte(S[Q+1]);
end;
end;
B:=CRC shr 1;
B:=not B;
result:=chr(B);
end;

Function TForm1.CalcCRC(s : string):Char;
Var
q,r,Crc:word;
B:byte;
begin
Crc:=Byte(S[1]);
B:=Byte(S[2]);
R:=0;
Q:=1;
CRC:=Crc shl 1;
while Q<6 do begin
if ((b and ($80 shr r))<>0) then CRC:=CRC or 1;
if CRC>=$100 then CRC:=CRC xor $107;
CRC:=CRC shl 1;
Inc(R);
if r=8 then begin
r:=0;
inc(q);
b:=Byte(S[Q+1]);
end;
end;
B:=CRC shr 1;
B:=not B;
result:=chr(B);
end;

end.
 
谢谢chenybin细心的回答,我把东西忘单位,
里面有一个正确的校验结果,我明天试了,OK就散分!
我今天仔细看了一下要求:他是这样的,比如要发送$43,$e8,$7d,$12,$56
每个字节分别对应01000011,11101000,01111101,00010010,01010110,再最后加上00000000
构成一个48位的码流,用他去除$107H的到一个余数,(其中有句话不明白:除的时候不相减而异或)把余数取反得到结果
谁能给个正确的答案 另加200分,主要是时间急
 
等你把正确的答案贴出来吧
 
像这种函数的声明,把参数声明为PChar/PBYTE似乎是最合适的,不过需要多加一个DataSize : Integer的参数,这是Win32API的通用方式
 
上面给的不对,大家帮忙哦
 
接受答案了.
 
正确答案呢?
 
后退
顶部