Не получается посчитать CRC

webmaster_Chris

Новичок
И так :-)) Задача :-) приходит пакет по сокету, который мы их bin2hex переводим. Получаем 41 03 56 89 60 34 06 01 61 45 69 00 00 00 00 00 00 00 00

Далее на такой пакет нужно устройству ответить это 4103568960340601610000000000 + CRC... Цитирую документацию:

При «авторизации» отправляются поля 1, 2, 5 (1+17+1=19 байт) (должен получить ответ CRC в виде resp_crc=xx, где xx – «посчитанная» сервером CRC)

CRC включает в себя все переданные байты (кроме самого байта CRC).
Перед передачей первого байта CRC устанавливается в 0x3B (GPRS_CRC=0x3B).
Функция расчета CRC (для каждого передаваемого байта):
void CRC (byte) {GPRS_CRC+=0x56^byte; GPRS_CRC++; GPRS_CRC^=0xC5+byte; GPRS_CRC--;}

т.е. пакет ответа получился 14 байт (без учета CRC) получается 56*14 отбрасываем последние цыфры, тоесть 784 -> 78 это CRC 16-ый байт.


Т.е. ответ 41035689603406016100000000003B78, через функцию:

PHP:
define('HEX2BIN_WS', " \t\n\r");                                                                                                                             
                                                                                                                                                             
function hex2bin($hex_string) {                                                                                                                              
$pos = 0;                                                                                                                                                    
$result = '';                                                                                                                                                
while ($pos < strlen($hex_string)) {                                                                                                                         
 if (strpos(HEX2BIN_WS, $hex_string{$pos}) !== FALSE) {                                                                                                      
 $pos++;                                                                                                                                                     
  } else {                                                                                                                                                   
 $code = hexdec(substr($hex_string, $pos, 2));                                                                                                               
 $pos = $pos + 2;                                                                                                                                            
 $result .= chr($code);                                                                                                                                      
}                                                                                                                                                            
}                                                                                                                                                            
return $result;                                                                                                                                              
}

засылаю устройству.. а в ответ нифига.. где я ошибаюсь, помогите подумать
 
Ну ладно CRC считается вот так:

PHP:
$GPRS_CRC=0x3B;                                                                                              
                                                                                                                                                             
$n=0;                                                                                                        
                                                                                                                                                             
while ($n<18){                                                                                               
 $GPRS_CRC+=0x56^$hex[$n];                                                                                    
 $GPRS_CRC++;                                                                                                 
 $GPRS_CRC^=0xC5+$hex[$n];                                                                                    
 $GPRS_CRC--;                                                                                                 
  $n++;                                                                                                        
}

но как посылать ответ то?
 
А что за устройство которому ты засылаешь ? Или нам телепата включать ?
GPRS_CRC - это один байт ?
 
Устройство AutoFon Mayak 4.5

Да GPRS_CRC это один байт... Даже скжу больше, вот что пишет их разработчик:

Расмотрим на примере, что от маяка пришел вот такой пакет авторизации:

41 03 56 89 50 38 77 67 98 45 68 00 00 00 00 00 00 00 07

в документации написано: crc передается ОДНИМ БАЙТОМ!
ответ должен быть из 10 байт: 9 из них - resp_crc=, а 10-й - сама crc.

То есть, для данного случая это будет выглядеть так:
resp_crc= - это 9 байт: 72 65 73 70 11 63 72 63 3D
сама crc - 10-й байт - (в данном случае - 07)

Итого ответ серверу на пакет авторизации должен выглядеть так
72 65 73 70 11 63 72 63 3D 07

нихрена не понимаю откуда взялось 72 65 73 70 11 63 72 63 3D....
 
Бред какой-то написан, честное слово. Уже начиная с первой строчки. С какого хрена ты трогаешь функцию bin2hex()? Зачем она тебе нужна? С какого хрена у тебя ответ получился в 14 байт? В документации тоже какая-то хрень написана: в ответе должны быть все переданные байты (их же передали 19) и CRC. 19 + 1 = 20, с какого хрена в примере их меньше? Бредятина. Подмена определений. То
CRC включает в себя все переданные байты
, то
crc передается ОДНИМ БАЙТОМ!
Бред.

т.е. пакет ответа получился 14 байт (без учета CRC) получается 56*14 отбрасываем последние цыфры, тоесть 784 -> 78 это CRC 16-ый байт
— это вообще написано под действием алкоголя, по-моему.
 
Приветствую! На самом деле там 19 байт - 1, т.е. в расчете CRC используется 18 байт, т.к. 19-й это и есть CRC... Но как ответить на пакет я не понимаю.. Пример вот есть: Это от устройства 41 03 56 89 50 38 77 67 98 45 68 00 00 00 00 00 00 00 07, а ответ ему должет бть такой 72 65 73 70 11 63 72 63 3D 07... Перебрал все... ну никак не получается.. формула расчета выше... но где ошибаюсь до сих пор не пойму...

Описание самого протокола: http://forum.autofon.ru/download/file.php?id=1&sid=1d57773fbd02e07da7d0d35e780d9733
 
Я так понял, что resp — просто некий ответ, который удовлетворяет требованиям какой-то спецификации. А вот последний байт ты и высчитываешь. Т.е. «resp_crc=xx» следует понимать как «ответ из 9-ти байт + CRC-код». Я так думаю.

Подсчёт CRC, кстати, такой:
PHP:
<?php

function crc($bytes)
{
    $r = 0x3B;

    for($i = 0; $i < strlen($bytes); $i++)
    {
        $r += 0x56 ^ ord($bytes[$i]);
        $r++;
        $r ^= 0xC5 + ord($bytes[$i]);
        $r--;
    }
    
    return $r & 0xFF;
}

printf('%02X', crc("\x41\x03\x56\x89\x50\x38\x77\x67\x98\x45\x68\x00\x00\x00\x00\x00\x00\x00"));
 
Если бы так было, то вот это 41 03 56 89 50 38 77 67 98 45 68 00 00 00 00 00 00 00 07 было бы равно вот этому 73 70 11 63 72 63 3D 07... тем неменее первое - 19 байт, второе 8... Так как получилось второе.. если формула:

CRC включает в себя все переданные байты (кроме самого байта CRC).
Перед передачей первого байта CRC устанавливается в 0x3B (GPRS_CRC=0x3B).
Функция расчета CRC (для каждого передаваемого байта):
void CRC (byte) {GPRS_CRC+=0x56^byte; GPRS_CRC++; GPRS_CRC^=0xC5+byte; GPRS_CRC--;}

А при той формуле, учитывая то, что поле 1 (41) должно входить в это получается 55... в примере же приведено 73... вот где то упускаю момент... ((
 
07 действительно получилось, но вот это откуда взялось: 73 70 11 63 72 63 3D и вот он crc 07
 
Если каждому запросу по какому-то алгоритму однозначно строится ответ, то тут сервер-клиент не нужен: этот «ответ» можно было бы получить сразу на локальной машине. И вообще я не понимаю что ты такое делаешь, что сам не представляешь что и для чего это нужно?
 
73 70 11 63 72 63 3D = "resp_crc=" вот что это оказывается... ))) Представлять то представляю, но с устртройствами такого плана работал... очень давно... Спасибо за помощь!
 
Я чё-то явно не понимаю: какой смысл в бинарном протоколе писать прямо фразу «resp_crc=»? Для кого?
 
Сверху