为财务打印机解码自定义 CRC 算法
Decoding Custom CRC algorithm for a fiscal printer
我在这里碰壁了,我需要你的帮助。我有一台财务打印机 (Datecs DP-50) 可以集成到一个 chrome 扩展应用程序上进行销售。问题是我们无法使用该驱动程序,因为该应用程序将 运行 a 在远程服务器上而不是在运营商设备上,我们必须发送原始数据。
在 PHP 中编码的应用程序使用 Laravel 5.1 作为额外信息。
所以我有一个带有自定义多项式 x^15+1 的以 16 为底数的 CRC,但它比那个多一点,我无法弄清楚。我将粘贴在手册中的文档下方。
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
例如,"A" 字符串的 CRC(仅 S1 和 S0)为十六进制:fe 09。对于 "B" => fc 09,对于 "C" => 7d f6 . "A" 的完整 CRC 校验码为 0d fe 09。
来自串行 COM 监视器的 TR 似乎是一个常量,始终表示为 0d hex。
感谢任何帮助解码的人。
提前致谢!
除了拼写错误外,该描述还存在缺陷,因为它遗漏了关键细节,即 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
.
我在这里碰壁了,我需要你的帮助。我有一台财务打印机 (Datecs DP-50) 可以集成到一个 chrome 扩展应用程序上进行销售。问题是我们无法使用该驱动程序,因为该应用程序将 运行 a 在远程服务器上而不是在运营商设备上,我们必须发送原始数据。 在 PHP 中编码的应用程序使用 Laravel 5.1 作为额外信息。
所以我有一个带有自定义多项式 x^15+1 的以 16 为底数的 CRC,但它比那个多一点,我无法弄清楚。我将粘贴在手册中的文档下方。
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
例如,"A" 字符串的 CRC(仅 S1 和 S0)为十六进制:fe 09。对于 "B" => fc 09,对于 "C" => 7d f6 . "A" 的完整 CRC 校验码为 0d fe 09。 来自串行 COM 监视器的 TR 似乎是一个常量,始终表示为 0d hex。
感谢任何帮助解码的人。 提前致谢!
除了拼写错误外,该描述还存在缺陷,因为它遗漏了关键细节,即 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
.