Если кто знает помогите разобраться. Решил разобраться как считается CRC для датчика DS18B20. Согласно теории, по команде BE мы получаем из памяти датчика 9 байт, последний из которых и есть CRC, который расчитывается по образующему полиному X ^ 8 + X ^ 5 + X ^ 4 + 1. Если записать полином в шеснадцатеричном виде то это будет 0х31. Подключаю датчик и получаю следующую последовательность байтов 0х92 0х01 0х4B 0x46 0x7F 0xFF 0x0C 0x10 0xB5 Открываю онлайн калькулятор https://crccalc.com/ Заганяю первые 8 байт и в строке CRC-8 / MAXIM получаем искомые 0xB5 (полином 0х31). Копал в интернете как осуществляется данная магия. Смог освоить только табличный метод. Результаты ручного расчёта совпали с полученными. Помогите вникнуть в магию процесса. Берём первый байт 0х92. В десятичном исчислении это 146. В таблице Спойлер: CRC8 0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, 0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E, 0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC, 0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0, 0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62, 0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D, 0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF, 0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5, 0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07, 0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58, 0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A, 0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6, 0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24, 0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B, 0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9, 0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F, 0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD, 0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92, 0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50, 0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C, 0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE, 0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1, 0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73, 0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49, 0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B, 0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4, 0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16, 0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A, 0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8, 0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7, 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35 на позиции 146 стоит 0xAD, ввожу в калькулятор 0х92 и получаю тот-же результат. Растолкуйте тупому, как из 0х92 и 0х31 получить 0хAD?
Код (C++): size_t i; unsigned char data[] = {0x92, 0x01, 0x4B, 0x46, 0x7F, 0xFF, 0x0C, 0x10}; unsigned char crcT = 0; for (i = 0; i < sizeof(data); i++) { crcT = tab[data[i] ^ crcT]; } printf("crcT 0x%02X\n", crcT); unsigned short crc8 = 0; for (i = 0; i < sizeof(data); i++) { crc8 = crc8 ^ data[i]; size_t n; for (n = 0; n < 8; n++) { if (crc8 & 0x01) { crc8 = crc8 >> 1; crc8 = crc8 ^ 0x8c; // 0x31=00110001b в зазеркалье он уже 10001100b=0x8c } else { crc8 = crc8 >> 1; } } } printf("crc8 0x%02X\n", crc8); результат расчета табличный и через константу 0x31 одинаковый получился Код (Text): crcT 0xB5 crc8 0xB5 У Максима есть скромный пример расчета
В исходнике табличный метод. На просторах интернета нарыл такой код Спойлер: код Код (C++): /* Name : CRC-8 Poly : 0x31 x^8 + x^5 + x^4 + 1 Init : 0xFF Revert: false XorOut: 0x00 Check : 0xF7 ("123456789") MaxLen: 15 байт(127 бит) - обнаружение одинарных, двойных, тройных и всех нечетных ошибок */ unsigned char Crc8(unsigned char *pcBlock, unsigned int len) { unsigned char crc = 0xFF; unsigned int i; while (len--) { crc ^= *pcBlock++; for (i = 0; i < 8; i++) crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1; } return crc; } Как я понял алгоритм следующий. Берём байт и смотрим на старший бит. Если бит равен 1 - сдвигаем его влево и делаем сложение по модулю 2 с полиномом (0х31) Если бит равен 0 - только слвигаем влево. Повторяем 8 раз. Проделал эту байду вручную с 0х92 Спойлер: расчёт 10010010 - исходное число проход 1 (старший бит - 1) 00100100 - сдвиг вправо 00010101 - XOR c 0x31 проход 2 (старший бит - 0) 00101010 - сдвиг влево проход 3 (старший бит - 0) 01010100 - сдвиг влево проход 4 (старший бит - 0) 10101000 - сдвиг влево проход 5 (старший бит - 1) 01010000 - сдвиг влево 01100001 - XOR c 0x31 проход 6 (старший бит - 0) 11000010 - сдвиг влево проход 7 (старший бит - 1) 10000100 - сдвиг влево 10110101 - XOR c 0x31 проход 8 (старший бит - 1) 01101010 - сдвиг влево 01011011 - XOR c 0x31 Вместо ожидаемого 0хAD получил 0х5B. Кто нибудь пробовал это осилить?