Текущий архив: 2008.02.03;
Скачать: CL | DM;
Вниззашился в вычислениях CRC , полистал кучу литературы, пообращался Найти похожие ветки
← →
aha (2008-01-02 23:14) [0]по конференциям , вернулся опять к вам . Известен полином $18F57.Есть кусок программы на С+ .Не хватает ума переделать на дельфи. Проверенная мной сумма для строки GVHGRILN, которая приводится к ввиду $0F10B257 равна $68A4.Не совсем понятен алгоритм на языке написанном С+. Может кто нибудь подскажет ?
unsigned short owenCRC16(unsigned char* packet, size_t length)
{
size_t i, j;
unsigned short crc;
assert(packet);
crc = 0;
for (i = 0; i < length; ++i)
{
unsigned char b = packet[i];
for (j = 0; j < 8; ++j, b <<= 1)
{
if ((b ^ (crc >> 8)) & 0x80)
{
crc <<= 1;
crc ^= 0x8F57;
}
else
crc <<= 1;
}
}
return crc;
}
← →
palva © (2008-01-02 23:22) [1]Если программа нужна для дела, то проще не переделывать, а откомпилировать борландовским компилятором и вставить объектный файл в паскаль.
Если же вы хотите потренировать голову и пальцы, то спрашивайте, какие конструкции в программе непонятны. Здесь найдется кому ответить.
← →
DVM © (2008-01-02 23:34) [2]
> aha
вот тебе тупой автоперевод
function owenCRC16(packet: pchar; length: size_t): word;
var
i: size_t;
j: size_t;
crc: word;
b: char;
begin
assert(packet);
crc:= 0;
for{while} i:=0 to Pred(length) { ++i}
do
begin
b:=packet[i];
while{for}
j:= 0;
{to} j<8
{;}
inc(j);
b:= b shl (1);
do
begin
if (b xor (crc shr 8)) and $80
then
begin
crc:= crc shl (1);
crc:= crc xor ($8F57);
end;
else
crc:= crc shl (1);
end;
end;
begin
result:= crc;
exit;
end;
end;
← →
aha (2008-01-03 09:24) [3]спасибо DVM
конечно надо еще перерабатывать , наверное
1.
var
i,j:integer;
//i: size_t;
//j: size_t;
2. assert(packet) не проходит у меня - никогда не пользовался функцией.
3. b:= b shl (1); b pchar не свдигается .
А в целом еще раз спасибо за уделенное внимание !!
← →
aha (2008-01-03 21:59) [4]Ничего не понимаю как ж на С+ все работает . Переделал на дельфи
таким образом
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
begin
owenCRC16("GVHGRILN",8);//хочу вычислить контр. сумму след. строки
end;
function owenCRC16(packet: pchar; length: integer): word;
var
i,j:integer;
crc: word;
b: char;
begin
crc:= 0;
for i:=0 to Pred(length) do
begin
b:=packet[i];
FOR J:=1 TO 8 DO
begin
if (ORD(B) xor (crc shr 8)) and $80 <>0
then
begin
crc:= crc shl (1);
crc:= crc xor ($8F57);
end
else
crc:= crc shl (1);
end;
end;
result:= crc;
FORM1.CAPTION:=INTTOSTR(CRC);
end;
контр. сумма должна быть $68A4, а судя по строке
if (ORD(B) xor (crc shr 8)) and $80 <>0 - она всегда будет равна 0 и следовательно CRC тоже
где моя ошибка ??
← →
icWasya © (2008-01-04 02:59) [5]например, если B = $80 и crc = 0, то
выражение
(ORD(B) xor (crc shr 8)) and $80
нулю не равно
← →
Германн © (2008-01-04 03:15) [6]
> зашился в вычислениях CRC , полистал кучу литературы, пообращался
> [D3]
>
> aha (02.01.08 23:14)
>
> по конференциям , вернулся опять к вам . Известен полином
> $18F57.
А причём тут "полином"?
← →
aha (2008-01-04 09:03) [7]2 icWasya
я имел ввиду для вычисления CRC для моей строки , где В никак не может быть $8X
2 Германн
причем полином ? ну вроде бы это образующий полином , для вычисления CRC . Может быть не корректно называю термины ...
← →
Evgeny V © (2008-01-04 09:26) [8]
> aha (04.01.08 09:03) [7]
Не разбирался с кодом на паскале подробно, который вы привели (как впрочем и на си), но один совет - использовать вместо типа char тип byte - так как unsigned char соотвествует типу байт(ну и использовать соотвествующие указатели). Далее в коде на си есть такой цикл
> for (j = 0; j < 8; ++j, b <<= 1)
Обращаю внимание - сдвиг вправо на разряд b <<= 1), а в коде на паскале я его не увидел. Что снимает спор о
> aha (03.01.08 21:59) [4]
> if (ORD(B) xor (crc shr 8)) and $80 <>0 - она всегда будет
> равна 0 и следовательно CRC тоже
> где моя ошибка ??
← →
Evgeny V © (2008-01-04 09:34) [9]
> Evgeny V © (04.01.08 09:26) [8]
> Обращаю внимание - сдвиг вправо на разряд b <<= 1
Естественно сдвиг влево, извиняюсь за ошибки "сено-солома"-:-)
← →
DVM © (2008-01-04 12:07) [10]
> А причём тут "полином"?
Притом, что образующий полином необходим для вычисления crc, только вот он взял какой то нестандартный полином. У CRC16 вроде $8005.
> Может быть не корректно называю термины
все верно.
Только непонятно, зачем тебе дался этот код на С. Пиши сразу на Delphi или возьми готовую функцию коих масса.
Теория тут: http://rsdn.ru/article/files/classes/SelfCheck/crcguide.pdf
← →
aha (2008-01-04 12:18) [11]2 DVM
да , я понимаю что не совсем стандартный полином , но дивайс работает именно с этим полином , читает CRC . А использую код С+ , так как изготовитель показал действующий код , я только пытаюсь подстроиться к нему
← →
DVM © (2008-01-04 12:21) [12]
> так как изготовитель показал действующий код
ох уж мне эти изготовители железяк, они постоянно придумывают свои варианты вычисления контрольных сумм, вместо того чтобы использовать общепринятые.
Я тебе вообще советую просчитать готовую таблицу для этого твоего полинома и потом ее использовать при расчетах. Так много быстрее будет. И проще.
← →
DVM © (2008-01-04 12:23) [13]
> aha
кстати, проверь свой полином на своих данных тут:
http://www.zorc.breitbandkatze.de/crc.html - так можно понять, стандартный или нет алгоритм подсчета контрольной суммы использовал производитель.
← →
aha (2008-01-04 12:39) [14]а насчет этой ссылки я могу сказать следующее , я показал на конф. телесис, и один из пользавателей проверив свои версии заявил , что данный калькулятор неправильно считает . ВОт кому верить то ? :-)
← →
DVM © (2008-01-04 12:49) [15]
> aha (04.01.08 12:39) [14]
ну его подсчеты (проверил CRC16) совпадают по крайней мере с подсчетами, которые выполняет программа WinHEX.
Вообще твой пост натолкнул меня тут на мысль написать правильный модуль на Delphi для расчета CRC всех видов, как стандартных, так и по собственнным полиномам. Займусь может сегодня.
← →
palva © (2008-01-04 13:42) [16]
> Вообще твой пост натолкнул меня тут на мысль написать правильный модуль на Delphi
Ссылка интересная. Если открыть исходный код странички то обнаружите, что всё уже написано на Java Script. Вас как любителя переводить с одного языка на другой это должно заинтересовать :)
← →
palva © (2008-01-04 13:47) [17]DVM © (04.01.08 12:49) [15]
> Вас как любителя переводить с одного языка на другой
Извините, перепутал. Это я над aha хотел пошутить, но не в того попал.
← →
DVM © (2008-01-04 13:59) [18]Посмотрел я готовые модули в интернет - все вычисляют CRC16 кто во что горазд. Точнее вычисляют правильно, но не ту CRC16. Полиномы разные и везде почти не соответствующие названию вычисляемой контрольной суммы.
← →
Anatoly Podgoretsky © (2008-01-04 14:06) [19]> DVM (04.01.2008 12:07:10) [10]
Вообще то говорить о стандарте как бы неприлично, есть общепринятые алгоритмы вычисления CRC16 и их есть не один, и с полиномомами и без. Поэтому когда говорим об алгоритме с полиномами, то указание полинома обязательно.
Вот моя старая функция 1996 года, расчета CRC32, которую легко переделать в CRC16 по любому полиному.
//*******************************
//* Calculate Crc32 with buf *
//*******************************
function BufToCrc(const Buf; Count:Integer) : Longint;
var
I : Integer;
begin
Result := $FFFFFFFF;
for I := 0 to Count - 1 do begin
Result := Crc32(Byte(TByteArray(Buf)[I]),Result);
end;
end;
//////////////////////////////////////////////////////////////////////////
// Crc32 - Data byte and Current Crc Value //
// POLYNOMIAL USED IS //
// X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 //
// CrcPolynominal = $04 C1 1D B7;
//////////////////////////////////////////////////////////////////////////
function Crc32(Data:Byte; CurrentCrc:Longint) : Longint; assembler;
asm
MOV ECX,8
@1:
ROL AL,1
RCL EDX,1
JNC @2
XOR EDX,CrcPolynominal
@2:
LOOP @1
MOV EAX,EDX
end;
← →
DVM © (2008-01-04 14:10) [20]
> Вообще то говорить о стандарте как бы неприлично, есть общепринятые
> алгоритмы вычисления CRC16 и их есть не один
вот я о том и говорю, что почти нигде не указывают, что вычисляется. Какой вариант CRC16. Некоторые вообще неправильно указывают.
← →
Anatoly Podgoretsky © (2008-01-04 14:25) [21]> DVM (04.01.2008 14:10:20) [20]
Да я с тобое совершенно согласен, поскольку встречался с подобным.
Но ты обратил внимание, что у меня указано :-)
← →
DVM © (2008-01-04 14:53) [22]
> aha
> сумма для строки GVHGRILN, которая приводится к ввиду $0F10B257
>
Вот этот момент кстати мне что то непонятен. Как из одного получается другое? Из $0F10B257 я получил CRC $68A4. Но откуда взялось 0F10B257?
← →
aha (2008-01-04 15:14) [23]запутался совсем , прочитал формат изготовителя и вот что я прочитал
Тетрады кодируются следующим образом:
0000 -> "G" = 0x47
0001 -> "H" = 0x48
0010 -> "I" = 0x49
0011 -> "J" = 0x4a
0100 -> "K" = 0x4b
0101 -> "L" = 0x4c
0110 -> "M" = 0x4d
0111 -> "N" = 0x4e
1000 -> "O" = 0x4f
1001 -> "P" = 0x50
1010 -> "Q" = 0x51
1011 -> "R" = 0x52
1100 -> "S" = 0x53
1101 -> "T" = 0x54
1110 -> "U" = 0x55
1111 -> "V" = 0x56
Короче все запутал , а полином используемый вот таков
x16+x15+x11+x10+x9+x8+x6+x4+x2+x1+x0.
Что то у Anatoly Podgoretsky подозрительно очень простой код получился , как его изменить для моего случая ??
← →
DVM © (2008-01-04 15:31) [24]
> aha (04.01.08 15:14) [23]
Короче, вот мой черновой вариант:var
CRC16Table: array[0..255] of WORD;
function crc16(Buffer: string; Polynom, Initial: Cardinal): Cardinal;
var
i, j: Integer;
begin
Result := Initial;
for i := 1 to Length(Buffer) do
begin
Result := Result xor (ord(buffer[i]) shl 8);
for j := 0 to 7 do
begin
if (Result and $8000) <> 0 then
Result := (Result shl 1) xor Polynom
else
Result := Result shl 1;
end;
end;
Result:=Result and $ffff;
end;
function GenerateTableCrc16(Poly: Cardinal): Cardinal;
var
i: Cardinal;
begin
for i:=0 to 255 do
CRC16Table[i] := Crc16(chr(i),Poly,0);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
begin
s := #$0F+#$10+#$B2+#$57;
GenerateTableCrc16($8F57);
caption := inttohex(Crc16Byte(s, 0), 4);
end;
← →
DVM © (2008-01-04 15:52) [25]забыл:
function Crc16Byte(Buffer:String;Initial:Cardinal):Cardinal;
var
i : Cardinal;
begin
Result:=Initial;
for i:=1 to Length(Buffer) do begin
Result:=(Result shl 8) xor CRC16Table[(ord(Buffer[i]) xor (Result shr 8)) and $ff];
end;
Result:=Result and $ffff;
end;
← →
aha (2008-01-04 18:33) [26]2 DVM
Здорово ! работает , вот что значит профессионал , понадобилось полчаса работы.....
Даже не знаю как отблагодарить , просто в восторге . Буду теперь разбираться в математике !!
Страницы: 1 вся ветка
Текущий архив: 2008.02.03;
Скачать: CL | DM;
Память: 0.52 MB
Время: 0.043 c