Расшифровка Custom CRC алгоритма для фискального принтера

Я попал в кирпичную стену, и мне нужна твоя помощь. У меня есть фискальный принтер (Datecs DP-50) для интеграции в приложение расширения Chrome, которое делает продажи. Проблема в том, что мы не можем использовать драйвер, так как приложение будет запускаться на удаленном сервере, а не на устройствах операторов, и мы должны отправлять данные в необработанном виде.
Приложение написано на PHP с использованием Laravel 5.1 в качестве дополнительной информации.

Итак, у меня есть база CRC 16 с пользовательским полиномом x ^ 15 + 1, но это немного больше, и я не могу понять это. Я вставлю ниже документацию из руководства.

   The two CRC bytes are calculated according to the formula x^15 + 1. In the
calculation are included all data bytes plus the byte for block end. Every byte passes
through the calculation register from teh MSB to LSB.
Three working bytes are used - S1, S0 and TR
S1 - Most significant byte from the CRC ( it is transmitted immediatelly after END)
S0 - Least significant byte from the CRC ( It is transmitted after S1)
TR - the current transmitted byte in the block.

The CRC is calculated as follows:
1. S1 and S0 are zeroed
2. TR is loaded with the current transmitted byte. The byte is transmitted.
3. Points 3.1 and 3.2 are executed 8 times:
3.1. S1, S0 and TR are shifted one bit to the left.
3.2. If the carry bit from S1 is 1, the MSB of S1 and LSB of S0 are inverted.
Points 2 and 3 are executed for all bytes, included in the calculation of the CRC - from
the first byte after BEG up to and including byte END.
4. TR is loaded with 0 and point 3 is executed
5. TR is loaded with 0 and point 3 is executed
6. Byte S1 is transmitted
7. Byte S0 is transmitted

Например, CRC (только S1 и S0) для строки «A» находится в шестнадцатеричном формате: fe 09. Для «B» => fc 09, для «C» => 7d f6. Полный CRC будет 0d fe 09 для «A».
TR из Serial COM Monitor выглядит как константа и всегда представлена ​​как 0d hex.

Любая помощь в расшифровке это приветствуется.
Заранее спасибо!

0

Решение

Описание является ошибочным, за исключением орфографических ошибок, в том смысле, что в нем пропущена важная деталь, которую регистры S1, S0, TR, в этом порядке, должны обрабатывать как один 24-битный регистр при сдвиге влево. Если вы сделаете это, вы получите результаты, которые вы цитируете. Вы должны включить 0x0d в расчете (байт «END»).

function crc16($crc, $byte) {
$crc = ($crc << 8) + $byte;
for ($k = 0; $k < 8; $k++)
$crc = ($crc & 0x800000) == 0 ? $crc << 1 : ($crc << 1) ^ 0x800100;
$crc = ($crc >> 8) & 0xffff;
return $crc;
}

$crc = 0;
$crc = crc16($crc, ord("A"));
$crc = crc16($crc, 13);
$crc = crc16($crc, 0);
$crc = crc16($crc, 0);
echo dechex($crc);

дает fe09,

1

Другие решения

Других решений пока нет …