Подтверждение обратной взаимной величины CR C -8? - PullRequest
0 голосов
/ 13 марта 2020

Я потратил довольно много времени, пытаясь подтвердить тип алгоритма CR C -8, используемого при передаче данных ASCII между двумя устройствами. Я подтвердил, что CR C рассчитывается для начального байта текста 0x02 + следующего байта данных. В документе «Дизайн интерфейса», который я описал для одного устройства, указано использование полинома 0xEA с начальным значением 0xFF. Ниже приведен пример одного захваченного сообщения:

Входные байты: 0x02 0x41

CR C Результат: b10011011 или 0x9B

Переходя к проблеме, я почти ничего не знал о внутренней работе типичного алгоритма CR C. Первоначально я попробовал ручной расчет по входным байтам, чтобы подтвердить свое понимание al go перед попыткой решения кода. Это включало в себя XOR 1-го входного байта с моим начальным значением 0xFF и затем переход ко второму входному байту для продолжения операций XOR.

Несколько раз пытался подтвердить CR C с помощью типичных операций XOR при сдвиге MSB исключали из реестра на каждом этапе, я никогда не мог получить результаты, которые я хотел. Сегодня я осознал, что полином 0xEA также считается обратной обратной величиной поли 0xD5 с подразумеваемым 1 + x ^ 8, который обычно используется в алгоритмах CR C -8. Как этот факт изменится, как я go подсчитал бы CR C вручную? Я читал, что в некоторых случаях обратное приводит к сдвигу вправо go вместо сдвига влево?

1 Ответ

1 голос
/ 13 марта 2020

Полином имеет вид x ^ 8 + x ^ 7 + x ^ 5 + x ^ 3 + x ^ 2 + x + 1 => 01AF бит, обращенный к x ^ 8 + x ^ 7 + x ^ 6 + x ^ 5 + x ^ 3 + x + 1 => 0x1EB. Пример кода, где условное XOR выполняется после сдвига, поэтому значение XOR равно 0x1EB >> 1 = 0xF5. 256-байтовый просмотр таблицы может быть использован для замены внутреннего l oop.

using System;
namespace crc8r
{
    class Program
    {
        private static byte crc8r(byte[] bfr, int bfrlen)
        {
            byte crc = 0xff;
            for (int j = 0; j < bfrlen; j++)
            {
                crc ^= bfr[j];
                for (int i = 0; i < 8; i++)
                    // assumes twos complement math
                    crc = (byte)((crc>>1)^((0-(crc&1))&0xf5));
            }
            return crc;
        }

        static void Main(string[] args)
        {
            byte[] data = new byte[3] {0x02, 0x41, 0x00};
            byte crc;
            crc = crc8r(data, 2);           // crc == 0x9b
            Console.WriteLine("{0:X2}", crc);
            data[2] = crc;
            crc = crc8r(data, 3);           // crc == 0x00
            Console.WriteLine("{0:X2}", crc);
            return;
        }
    }
}

Относительно "EA", если полином XOR'ed перед сдвигом, 0x1EB (или 0x1EA, так как бит 0 будет сдвинут и не имеет значения) используется. Для выполнения XOR перед сдвигом требуется 9 бит, или после сдвига ИЛИ или XOR 0x80, в то время как для XOR после сдвига требуется только 8 бит.

Пример строки кода с использованием 0x1eb до сдвига:

                    crc = (byte)((crc^((0-(crc&1))&0x1eb))>>1);
...