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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.036 c
1-1084854227
Azazzello
2004-05-18 08:23
2004.05.30
Строка с запятыми!


14-1084502074
Helpme
2004-05-14 06:34
2004.05.30
Извините


9-1074633038
Alex Storm
2004-01-21 00:10
2004.05.30
Создание ландшафта на GLScene


14-1084092082
nikkie
2004-05-09 12:41
2004.05.30
Новая версия DMClient - 2.1.1


14-1084332023
Medic
2004-05-12 07:20
2004.05.30
ресурсы И-нета по ООП.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский