CRC8 как посчитать

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Ответить
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

CRC8 как посчитать

Сообщение Attid »

Всем привет!

столкнулся тут с необходимостью считать црц. в документации :

Контрольная сумма CRC8 по полям Id и Data (без учета маскирования).
Начальное значение: 0xFF (Полином: x 8 +x 5 +x 4 +1 / 0x31 / “CRC-8-Dallas/Maxim”).

методом тыка нашел что команда
#$7D#$C1#$00#$06#$00#$00#$47 дает crc #$31
#$B8#$C1#$00#$06#$00#$00#$47 дает crc #$CD

пробовал разные варианты, последний

Код: Выделить всё

function TKKM_5200K.CRC3(Data: string): string;
var i,c,j:cardinal;
  Value: word;
begin
  Value := $FF;

  for j := 1 to Length(Data) do
  begin

    Value := Value xor Ord(Data[j]);
    for i := 0 to  8 do
    begin
      if odd(Value) then
        //1Value := (Value shr 1) xor $31
        Value:=((Value xor $31) shr 1) or $80
      else
        Value := (Value shr 1);
    end;

  end;

  result := char(Value);

end;


но результат не тот. может кто сталкивался ?
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

В конце перед выходом нужно делать

Код: Выделить всё

Result := Result xor $FF;
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

serbod писал(а):В конце перед выходом нужно делать

Код: Выделить всё

Result := Result xor $FF;


а вначале Value := $FF; убрать ?

хотя сейчас проверю так и так =)

Добавлено спустя 1 час 50 минут 53 секунды:
нашел калькулятор который считает
http://zorc.breitbandkatze.de/crc.html
если сделать вот такие настройки
Выделение_025.png


судя по насройкам должно быть так :

Код: Выделить всё

function TKKM_5200K.CRC3(Data: string): string;
var iLen,i8:cardinal;
  Value: Byte;
begin
  Value := $FF;
  //Value := $00;

  for iLen := 1 to Length(Data) do
  begin

    Value := Value xor Ord(Data[iLen]);
    for i8 := 0 to 7 do
    begin
      if odd(Value) then
        Value := (Value shr 1) xor $31
        //Value:=((Value xor $31) shr 1) or $80
      else
        Value := (Value shr 1);
    end;

  end;

  Value := Value xor $00;

  result := char(Value);

end;   

но толку ноль. смотрел исходник на яваскрипт но там так дофига условий, что теряюсь. есть тут спец по яваскрипту ?
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

Там же есть ссылка на исходник на Си:

Код: Выделить всё

      crc = crcinit;
      for (i=0; i<order; i++) {

         bit = crc & 1;
         if (bit) crc^= polynom;
         crc >>= 1;
         if (bit) crc|= crchighbit;
      }   


Судя по коду, в цикле сперва происходит XOR на полином, а потом уже сдвиг.

Код: Выделить всё

      if odd(Value) then
        Value := ((Value xor $31) shr 1)
      else
        Value := (Value shr 1);
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

Конечный вариант который получился благодаря serbod

Код: Выделить всё

function CRC8(Data: string): string;
var  iLen, i8: Integer;  Value: Byte;
begin
  Value := $FF;
  for iLen := 1 to Length(Data) do
  begin
    Value := Value xor Ord(Data[iLen]);
    for i8 := 0 to 7 do
    begin
      if (Value and $80) <> 0 then
        Value := ((Value shl 1) xor $31)
      else
        Value := (Value shl 1);
    end;
  end;
  Value := Value xor $00;
  result := Char(Value);
end; 


может кто искать еще будет добавлю ключи CRC CRC8 ATOL 3.0 АТОЛ 3.0
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Value := Value xor $00;
??
Cyr
незнакомец
Сообщения: 2
Зарегистрирован: 15.11.2018 19:28:56

Сообщение Cyr »

Код: Выделить всё

      if (Value and $80) <> 0 then
        Value := ((Value shl 1) xor $31)
      else
        Value := (Value shl 1);

можно заменить на

Код: Выделить всё

      flag := (Value and $80); 
      Value := (Value shl 1);       
      if (flag <> 0) then Value := (Value xor $31);

Т.е. по сути в ассемблере XOR делается только при взведённом флаге переполнения (переносе) после сдвига.
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

Можно в одну строчку и без условных переходов

Код: Выделить всё

  Value := (Value shl 1) xor ($31 and SarShortint(Value, 7));

:wink:
Ответить