Преобразование 8-битной функции CRC, написанной на C, в переполнение стека

Я пытаюсь преобразовать функцию C в PHP, который выполняет 8-битное вычисление CRC.

Оригинальный код C:

uint8_t CRCCalc (uint8_t* pointer, uint16_t len) {

uint8_t CRC = 0x00;

uint16_t tmp;

while(len > 0) {

tmp = CRC << 1;

tmp += *pointer;

CRC = (tmp & 0xFF) + (tmp >> 8);

pointer++;

--len;

}

return CRC;

}

PHP-код, который я придумал:

function crc8_calc($hex_string)
{
$bin_data = pack('H*',$hex_string);
$bin_length = strlen($bin_data);

$CRC    =   0x00;
$pos    =   0;

while($bin_length>0)
{
//$pos = $CRC << 1;

$CRC = ($bin_data[$pos] & 0xFF) + ($bin_data[$pos] >> 8);
$bin_length --;
$pos++ ;
}

return $CRC;
}

Есть что-то, чего не хватает, так как результаты функций PHP неверны. Я не очень знаком с C, поэтому не уверен, что мое преобразование правильное. Функция C выдает правильный CRC

Например, если шестнадцатеричное представление строки:
280500000805151001240000000010017475260004041001372068828503000000000000

КПР должен быть D4.

Я уже видел следующие ссылки для расчета CRC8, но мне кажется, что-то не хватает

как сгенерировать 8bit CRC в PHP
CRC8-проверка в PHP

Из этого ответа я также взял несколько бит моего кода преобразования
Конвертировать C в PHP для функции CRC16

2

Решение

Попробуйте это так:

function crc8_calc($hex_string)
{
$bin_data = pack('H*',$hex_string);
$bin_length = strlen($bin_data);

$CRC = 0;
$tmp = 0;
$pos = 0;

while($bin_length>0)
{
$tmp = $CRC << 1;
$tmp = $tmp + ord($bin_data[$pos]); //Added ord

$CRC = ($tmp + ($tmp >> 8)) & 0xFF;
$bin_length --;
$pos++ ;
}
return $CRC;
}
2

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

Очевидно, что два фрагмента кода не делают одно и то же. В функции C первое, что происходит: вы сдвигаете CRC (который вы уже рассчитали) влево на 1 бит (то же самое, что умножаете его на 2), затем добавляете следующий байт из массива и затем пересчитываете CRC, сложив вместе два байта tmp.

Ваш пример PHP не выполняет начальный сдвиг и не смешивает предыдущую версию CRC с вычислением для следующего байта.

3

($tmp & 0xFF) просто младший байт

($tmp >> 8) сдвиг вправо 8

Я не проверял, но это быстрая попытка.

function CRCCalc ($value, $len) {
$CRC = 0;
while($len > 0) {
$tmp = $CRC << 1;  // shift left 1
$tmp += $value;
$CRC = ($tmp & 0xFF) + ($tmp >> 8); //  ($tmp & 0xFF) just lower byte    ($tmp >> 8: shift right 8
$value++;
$len--;
}
return $CRC;
}
0
По вопросам рекламы [email protected]