![]() |
|
|
#1
|
|||
|
|||
|
Надо подсчитать контрольную сумму пол полиному X^16+X^15+X^2+1.
есть код: Код:
var
Form1: TForm1;
implementation
CONST crctab: ARRAY[0..255] OF WORD = (
$0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
$8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef,
$1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6,
$9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de,
$2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485,
$a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d,
$3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4,
$b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc,
$48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823,
$c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b,
$5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12,
$dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a,
$6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41,
$edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49,
$7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70,
$ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78,
$9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f,
$1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067,
$83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e,
$02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256,
$b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d,
$34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405,
$a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c,
$26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634,
$d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab,
$5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3,
$cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a,
$4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92,
$fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9,
$7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1,
$ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8,
$6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0);
{$R *.dfm}
function crc16(cp:Byte;crc:WORD):Word;
begin //UpdCrc
crc16:= crctab[((crc SHR 8) AND 255)] XOR (crc SHL 8) XOR cp
end;
procedure TForm1.btn1Click(Sender: TObject);
var
crc:Word;
i:Integer;
Buf:byte;
begin
if length(edt3.text)=0 then ShowMessage('Поле входных данных не заполнено');
crc:=$FFFF;
for i:=1 to Length(edt3.Text) do
begin
crc:=crc16(byte(edt3.Text[i]),crc);
end;
edt2.Text:=IntToHex(crc,0);
end;Где я не прав? Почему выдается не верный ответ? Заранее благодарен. |
|
#2
|
|||
|
|||
|
Может кто поможет переконвертировать код С в Delphi?
while (len--) crc = (crc >> 8) ^ Crc16Table[(crc & 0xFF) ^ *pcBlock++]; return crc; |
|
#3
|
||||
|
||||
|
Я помогу, если дашь не "отгрызок" кода, а полный фрагмент.
Да и зачем? Google, запрос "crc16 delphi" Третий результат - ссылка на тему в "programmersforum", где есть прямая ссылка на юнит CRC16/32 с примером использования. Но, насколько я понял, ошибка гораздо проще. Тут: Код:
crc:=$FFFF; crc:=0; Последний раз редактировалось PhoeniX, 28.06.2010 в 13:57. |
|
#4
|
|||
|
|||
|
Я по этому примеру и делаю.
crc должен принимать значение $FFFF (данные с вики) -> Код:
Name : CRC-16
Poly : 0x8005 x^16 + x^15 + x^2 + 1
Init : 0xFFFF
Revert: true
XorOut: 0x0000
Check : 0x4B37 ("123456789")
MaxLen: 4095 байт (32767 бит) - обнаружение
одинарных, двойных, тройных и всех нечетных ошибокНо я пробовал и с 0, все равно считает не верно: так как при вычислении КС, ответ приписанный к входным данным, при повторном вычислении, должен возвращать в ответ 0. Т.е. Вх: F70302640008 КС: 10FD. А при Вх: F7030264000810FD КС: 00 . Вот так должна работать программа. А у меня получается с начальным значением Crc =$FFFF: Вх: F70302640008 КС:712C Вх: F70302640008712C КС: 4F55. С начальным значением CRC = 0: Вх: F70302640008 КС: F5D5. Вх: F70302640008F5D5 КС: 28C5. Еще сейчас пришлю весь код программы. |
|
#5
|
|||
|
|||
|
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
lbl1: TLabel;
lbl2: TLabel;
lbl3: TLabel;
btn1: TButton;
btn2: TButton;
edt2: TEdit;
edt3: TEdit;
btn3: TButton;
procedure btn2Click(Sender: TObject);
procedure btn1Click(Sender: TObject);
procedure edt3KeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
CONST crctab: ARRAY[0..255] OF WORD = (
$0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
$8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef,
$1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6,
$9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de,
$2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485,
$a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d,
$3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4,
$b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc,
$48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823,
$c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b,
$5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12,
$dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a,
$6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41,
$edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49,
$7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70,
$ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78,
$9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f,
$1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067,
$83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e,
$02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256,
$b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d,
$34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405,
$a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c,
$26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634,
$d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab,
$5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3,
$cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a,
$4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92,
$fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9,
$7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1,
$ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8,
$6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0);
{$R *.dfm}
function crc16(data:Byte;crc:WORD):Word;
begin //UpdCrc
crc16:=crctab[((crc shr 8) and 255)] xor (crc SHL 8) XOR data ;
end;
procedure TForm1.btn2Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.btn1Click(Sender: TObject);
var
crc:Word;
i,j:Integer;
st:string;
begin
if length(edt3.text)=0 then ShowMessage('Поле данных пусто');
crc:=$FFFF;
for i:=1 to Length(edt3.Text) do
begin
crc:=crc16(Byte(edt3.Text[i]),crc);
end;
edt2.Text:=IntToHex(crc,0);
end;
procedure TForm1.edt3KeyPress(Sender: TObject; var Key: Char);
begin
if Key in [#8,'0'..'9','a'..'f','A'..'F'] then Key:=System.UpCase(Key) else
begin
ShowMessage('Недопустимый формат данных');
Key:=#0;
end;
end; |
|
#6
|
||||
|
||||
|
У меня логичный вопрос: Вы в поле "Edt3" вводите значение в каком виде? HEX? Тогда вам надо считывать из Edit по ДВА символа и переводить их в байты, а не просто преобразовывать...
Код:
Procedure TForm1.btn1Click(Sender: TObject);
Var
crc: Word;
i: Integer;
b: Byte;
Begin
If edt3.text = '' Then // Лишняя функция Length была
ShowMessage('Поле данных пусто');
Else Begin // Если поле данных было не пусто - продолжаем
crc := $FFFF; // crc := 0; ?
i := 1;
While i<Length(edt3.Text) Do Begin
b := StrToInt('$' + edt3.Text[i] + edt3.Text[i + 1]); // Преобразуем 2 символа в байт
crc := crc16(b, crc);
inc(i, 2); // Смещаем позицию на 2 символа
End;
End;
edt2.Text := IntToHex(crc, 0);
End;Последний раз редактировалось PhoeniX, 28.06.2010 в 17:11. |
|
#7
|
|||
|
|||
|
Спасибо, теперь понял.
только вот видимо проблема у меня еще и функции crc16, так как при вычислении КС, ответ приписанный к входным данным, при повторном вычислении, должен возвращать в ответ 0. Т.е. Вх: F70302640008 КС: 10FD. А при Вх: F7030264000810FD КС: 00. Код:
function crc16(data:Byte;crc:WORD):Word; begin //UpdCrc crc16:=crctab[((crc shr 8) and 255)] xor (crc SHL 8) XOR data ; end; А получается: Вх: F70302640008 КС: D368 Вх: F70302640008D368 КС: 7EB2 все С# функция выглядит вот так Код:
unsigned short Crc16(unsigned char * pcBlock, unsigned short len)
{
unsigned short crc = 0xFFFF;
while (len--)
crc = (crc >> 8) ^ Crc16Table[(crc & 0xFF) ^ *pcBlock++];
return crc;может найдутся люди, которые перефразируют ее в Delphi? |
|
#8
|
||||
|
||||
|
Код:
crc = (crc >> 8) ^ Crc16Table[(crc & 0xFF) ^ *pcBlock++]; Код:
crc:= (crc srh 8) xor Crc16Table[(crc and $FF) xor data]; А где ты вот такое Код:
crc16:=crctab[((crc shr 8) and 255)] xor (crc SHL 8) XOR data ; ============== Добавлено спустя 100500 секунд Нашёл, вопрос снят. Хрен знает, что это значит. Но вроде не одно и то же. Последний раз редактировалось PhoeniX, 29.06.2010 в 00:48. |
|
#9
|
|||
|
|||
|
Спасибо, всем! Все заработало.
выкладываю рабочий код. Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
lbl1: TLabel;
lbl2: TLabel;
lbl3: TLabel;
btn1: TButton;
btn2: TButton;
edt2: TEdit;
edt3: TEdit;
btn3: TButton;
procedure btn2Click(Sender: TObject);
procedure edt3KeyPress(Sender: TObject; var Key: Char);
procedure btn1Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type TBuffer = array of Byte;
var
Form1: TForm1;
implementation
CONST crctab: ARRAY[0..255] OF WORD = (
$0000, $C0C1, $C181, $0140, $C301, $03C0, $0280, $C241,
$C601, $06C0, $0780, $C741, $0500, $C5C1, $C481, $0440,
$CC01, $0CC0, $0D80, $CD41, $0F00, $CFC1, $CE81, $0E40,
$0A00, $CAC1, $CB81, $0B40, $C901, $09C0, $0880, $C841,
$D801, $18C0, $1980, $D941, $1B00, $DBC1, $DA81, $1A40,
$1E00, $DEC1, $DF81, $1F40, $DD01, $1DC0, $1C80, $DC41,
$1400, $D4C1, $D581, $1540, $D701, $17C0, $1680, $D641,
$D201, $12C0, $1380, $D341, $1100, $D1C1, $D081, $1040,
$F001, $30C0, $3180, $F141, $3300, $F3C1, $F281, $3240,
$3600, $F6C1, $F781, $3740, $F501, $35C0, $3480, $F441,
$3C00, $FCC1, $FD81, $3D40, $FF01, $3FC0, $3E80, $FE41,
$FA01, $3AC0, $3B80, $FB41, $3900, $F9C1, $F881, $3840,
$2800, $E8C1, $E981, $2940, $EB01, $2BC0, $2A80, $EA41,
$EE01, $2EC0, $2F80, $EF41, $2D00, $EDC1, $EC81, $2C40,
$E401, $24C0, $2580, $E541, $2700, $E7C1, $E681, $2640,
$2200, $E2C1, $E381, $2340, $E101, $21C0, $2080, $E041,
$A001, $60C0, $6180, $A141, $6300, $A3C1, $A281, $6240,
$6600, $A6C1, $A781, $6740, $A501, $65C0, $6480, $A441,
$6C00, $ACC1, $AD81, $6D40, $AF01, $6FC0, $6E80, $AE41,
$AA01, $6AC0, $6B80, $AB41, $6900, $A9C1, $A881, $6840,
$7800, $B8C1, $B981, $7940, $BB01, $7BC0, $7A80, $BA41,
$BE01, $7EC0, $7F80, $BF41, $7D00, $BDC1, $BC81, $7C40,
$B401, $74C0, $7580, $B541, $7700, $B7C1, $B681, $7640,
$7200, $B2C1, $B381, $7340, $B101, $71C0, $7080, $B041,
$5000, $90C1, $9181, $5140, $9301, $53C0, $5280, $9241,
$9601, $56C0, $5780, $9741, $5500, $95C1, $9481, $5440,
$9C01, $5CC0, $5D80, $9D41, $5F00, $9FC1, $9E81, $5E40,
$5A00, $9AC1, $9B81, $5B40, $9901, $59C0, $5880, $9841,
$8801, $48C0, $4980, $8941, $4B00, $8BC1, $8A81, $4A40,
$4E00, $8EC1, $8F81, $4F40, $8D01, $4DC0, $4C80, $8C41,
$4400, $84C1, $8581, $4540, $8701, $47C0, $4680, $8641,
$8201, $42C0, $4380, $8341, $4100, $81C1, $8081, $4040 );
{$R *.dfm}
function crc16(twoSym:array of Word; size:Word):Word;
var
i:Integer;
crc:Word;
begin
crc:=$FFFF;
for i:=0 to ((size div 2)-1) do
begin
crc:= (crc shr 8) xor CrcTab[(crc and $FF) xor twoSym[i]];
end;
Result:=crc;
end;
function StrToByte(p1:string):integer;
const hex:array['A'..'F'] of Word=(10,11,12,13,14,15);
var
Int,i:Integer;
begin
Int:=0;
for i := 1 to Length(P1) do
if P1[i] < 'A' then Int := Int * 16 + ORD(P1[i]) - 48
else Int := Int * 16 + HEX[p1[i]];
Result:=int;
end;
procedure TForm1.btn2Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.edt3KeyPress(Sender: TObject; var Key: Char);
begin
if Key in [#8,'0'..'9','a'..'f','A'..'F'] then Key:=System.UpCase(Key) else
begin
ShowMessage('Недопустимый формат');
Key:=#0;
end;
end;
Procedure TForm1.btn1Click(Sender: TObject);
Var
crc: Word;
i,j: Integer;
b: array[1..100] of Word;
Begin
If edt3.text = '' Then
ShowMessage('Поле данных пусто')
Else
Begin
j:=1;
for i := 1 to Length(edt3.Text) do
begin
b[i]:=StrToByte(edt3.Text[j]+edt3.Text[j+1]);
j:=j+2;
end;
crc:= crc16(b, Length(edt3.Text));
edt2.Text :=IntToHex(crc, 2);
End;
End;
procedure TForm1.btn3Click(Sender: TObject);
var
D:Word;
i:Integer;
begin
edt2.Clear;
for i := 1 to Length(edt3.Text) do
begin
D:=StrToByte(edt3.Text[i]);
edt2.Text:=edt2.Text+IntToHex(D,0);
end;
end;
end. |
|
#10
|
|||
|
|||
|
Еще маленький вопрос.
Где менять отображение в поле edit, справа налево и наоборот? Т.е. Программа высчитывает CRC=FD10 последовательности F70302640008. А надо, чтоб отображалось 10FD, так как это верный ответ. |
|
#11
|
|||
|
|||
|
Усе, Гуд!
Функцию просто надо было поправить вот так. Код:
function crc16(twoSym:array of Word; size:Word):Word;
var
i:Integer;
crc:Word;
begin
crc:=$FFFF;
for i:=0 to ((size div 2)-1) do
begin
crc:= (crc shr 8) xor CrcTab[(crc and $FF) xor twoSym[i]];
end;
Result:=(crc shr 8) or (crc shl 8);
end;Кто считает, что извращено слишком, готов услышать конструктивную критику=) |