Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.30;
Скачать: CL | DM;

Вниз

CRC16   Найти похожие ветки 

 
fantomas ©   (2004-04-25 03:57) [0]

Уважаемые специалисты.
Научите дурака, как посчитать CRC. Необходимо при записи в COM порт добавлять CRC16. Перерыл весь Инет, нашел кучу информации, но до конца так и не понял. Мне бы какой-нибудь реальный пример подсчета , ну например вот для такой строки: F1 00 00 0A 00 00 00 12. Или для какой-нибудь другой, неважно. Спасибо.


 
Павел   (2004-04-25 10:23) [1]

В общем случае CRC16 считается так:

Function CalculateCRC16(P : PChar; Len : Word) : Word;
Var iByte, i : Word; B : Byte;
Begin
{$R-}
{инициализация}
Result:= $FFFF;
{цикл по всем байтам буфера}
For iByte:= 0 to Len-1 do begin
 {очередной байт буфера}
 B:= Byte(Pointer(LongInt(P)+iByte)^);
 {вычисление очередного CRC}
 Result:= (Result and $FF00) + (B xor Lo(Result));
 For i:= 1 to 8 do begin
  If ((Result and $0001) <> 0) then
   Result:= (Result shr 1) xor $A001
  Else
   Result:= (Result shr 1);
 End;
End;
{$R+}
End;
Однако это довольно медлено, поэтому обычно строят спец. таблицу, в которой уже вычеслены сдвиги для каждого байта. Подробнее (и кучу другим методов для контрольных сумм) читайте тут:
http://bhv.ftk.spbstu.ru/books/book.php?id=2732
http://www.ozon.ru/context/detail/id/1656093/


 
Andrew_Rostov   (2004-04-25 10:33) [2]

Я нарыл библиотеку специально для этих целей - там и CRC16/32 и MD5 и еще куча разных алгоритмов:
Availble hash types:
HASH_MD2, HASH_MD4, HASH_MD5,
HASH_CRC32, HASH_CRC32B,
HASH_ADLER32,
HASH_GOST,
HASH_HAVAL128, HASH_HAVAL160,
HASH_HAVAL192, HASH_HAVAL224,
HASH_HAVAL256,
HASH_SHA1, HASH_SHA256, HASH_SHA384, HASH_SHA512,
HASH_TIGER128, HASH_TIGER160, HASH_TIGER192,
HASH_RIPEMD128, HASH_RIPEMD160.
Называется HashLib!


 
Anatoly Podgoretsky ©   (2004-04-25 10:46) [3]

Тебе что все равно какой? Тогда все равно какой алгоритм, хоть складывай байты.


 
GEN++ ©   (2004-04-25 13:51) [4]

Для справки .
Вычисление контрольного циклического кода производится путем логического деления битовой
последовательности полученной из последовательно составленных байтов информационного блока на
образующий полином вида X^(16) + X^(15)+... +X^(2) +1
Алгоритм программного вычисления CRC.
1 . Загрузить двухбайтовый регистр (назовем его CRC- регистром ) начальным значением CRC.
2. Сложить по модулю 2 ( исключительное "ИЛИ") младший байт CRC- регистра с первым байтом
последовательности и поместить результат в CRC-регистр .
3. Сдвинуть вправо CRC-регистр на флаг переноса (старший бит старшего байта заместить нулем ).
4. Если флаг переноса = 0, повторить п .3
Если флаг переноса =1, сложить по модулю 2 содержимое CRC- регистра с константой $0A00 ;
результат поместить в CRC- регистр .
5. Повторять п .3, п .4 пока общее количество сдвигов не станет равно 8.
6. Повторить п .2 для следующего и остальных байтов последовательности .
7. Получившееся в результате действий по п1. ... п6. значение CRC- регистра является контрольным
циклическим кодом всей последовательности .

Для популярного протокола обмена "Modbus" начальное значение CRC=$FFFF
Функция вычислнгия CRC16, работающая в реальной аппаратуре (протокол Modbus).

function Modbas_CHSM(stA,KB:word;Buffer:pointer):word;
    //подсчет контрольной суммы байтовой последовательности
   //записанной в буфере, на который указывает Buffer:pointer
   //KB - количество байт в блоке  для подсчета конторольной суммы
   //stA - начального элемента в массиве на который указывает Buffer
   //возвращает 2-х байтовое CRC
   //начальное значение CRC=$FFFF
type
pB=^Byte;
var
ctBt:word;
ctShift:word;
CRC,CRC1:word;
flC:boolean;
loCRC,hiCRC,x:byte;
CRC_lo:word;
teckB:byte;
B:pB;
const
CRC_st:word=$FFFF;
CRC_1:word=$A001;
begin
      B:=pB(Buffer);
      inc(B,stA);
      CRC:=CRC_st;
      for ctBt:=stA to stA+KB-1 do
      begin
            ctShift:=0;
            CRC_lo:=CRC and $FF; //мл байт CRC
            CRC:=CRC and $FF00;              
               teckB:=B^; //************
            //CRC=ст байт CRC + мл байт CRC xor masKom[ctBt]
            CRC:=CRC or (CRC_lo xor teckB{masKom[ctBt]});
         repeat
            if CRC and 1 >0 then flC:=true else flC:=false;
               CRC:=CRC shr 1;
                  inc(ctShift);
            if (flC) {and (ctShift<8)} then  CRC:=CRC xor CRC_1;
         until ctShift=8;
         inc(B);
      end;
      result:=CRC;
end;


 
VKhoroz   (2004-04-26 12:12) [5]

See here
//CRC algorithm courtesy of Earl F. Glynn ...
//(http://www.efg2.com/Lab/Mathematics/CRC.htm)


 
fantomas ©   (2004-04-26 20:23) [6]

Большое спасибо за помощь. Кажись разобрался.



Страницы: 1 вся ветка

Текущий архив: 2004.05.30;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.059 c
7-1083140461
Pul
2004-04-28 12:21
2004.05.30
Как программно установить в биосе время включения компьютера


14-1084447526
Tamagoci
2004-05-13 15:25
2004.05.30
Использование Thread при обновлении состояния Action ов


3-1083736337
TATIANA
2004-05-05 09:52
2004.05.30
Хранимая процедура - запрос - BLOB - поле


14-1084006487
uny
2004-05-08 12:54
2004.05.30
По другому теперь?


6-1081499243
Srg
2004-04-09 12:27
2004.05.30
TMemoryStream &amp; TidTCPServer