Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.02.03;
Скачать: [xml.tar.bz2];

Вниз

зашился в вычислениях 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.062 c
3-1190756478
vladimir_Lav
2007-09-26 01:41
2008.02.03
Временная таблица в MSSQL


2-1199652100
223001
2008-01-06 23:41
2008.02.03
уважаемые мастера delphi подскажите как сделать кнопку


2-1199972940
AntonUSAnoV
2008-01-10 16:49
2008.02.03
как открыть файл из delphi


15-1198422204
Sergey Masloff
2007-12-23 18:03
2008.02.03
А почему просто не удалять мусорные ветки?


15-1199046225
Petr V. Abramov
2007-12-30 23:23
2008.02.03
Automate BPA Server 7





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский