nokepp 0 28 января, 2011 Опубликовано 28 января, 2011 · Жалоба Все добрый день! необходимо написать программу, простенькую, для расчета контрольной суммы по алгоритму crc8.Собственно говоря, я в С++ только только начал разбираться :smile3046: , но вот появилась такая задача и можно сказать зашился. Хочу, что бы просто в командной строке вводишь данные и сразу выдает ответ. Данные hex. Алгоритм программы таков public class CRC8 { private static int getCrc(int oneByte, int crc){ int i = oneByte ^ crc; crc = 0; if((i & 0x01)>0) crc ^= 0x5e; if((i & 0x02)>0) crc ^= 0xbc; if((i & 0x04)>0) crc ^= 0x61; if((i & 0x08)>0) crc ^= 0xc2; if((i & 0x10)>0) crc ^= 0x9d; if((i & 0x20)>0) crc ^= 0x23; if((i & 0x40)>0) crc ^= 0x46; if((i & 0x80)>0) crc ^= 0x8c; return crc; } byte[] bytes = {(byte)0x31,(byte)0xFF,(byte)0x06}; System.out.printf("crc=%X\n",CRC8.getCrc4Array(bytes)); Сразу скажу, что возможно он отличается от привычных всем, ибо этот алгоритм разработан производителями переферийнного устройства и, подсчитывая crc в ручную, у меня не совпадало значение моего crc со значением производителя . Я писал им support :1111493779: , но они отказываются мне помогать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 28 января, 2011 Опубликовано 28 января, 2011 · Жалоба и, подсчитывая crc в ручную, у меня не совпадало значение моего crc со значением производителя Ну так приведите набор данных и получившуюся у вас и у них crc. По строке if((i & 0x80)>0) crc ^= 0x8c; это должен быть CRC имени Далласа от 1-wire, остальные строки не проверял на правильность. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 28 января, 2011 Опубликовано 28 января, 2011 · Жалоба Сразу скажу, что возможно он отличается от привычных всем, ибо этот алгоритм разработан производителями переферийнного устройства и, подсчитывая crc в ручную О! Это совершенно секретный :), как уже заметил Сергей полином X^8+X^5+X^4+X^0 имении Dallas. Считается оптимальным для коротких последовательностей. Считается, как и любой CRC массой способов. Хоть по таблице: const BYTE crc8_8540_tbl[]= { 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 }; хоть другими отличными от Вашего софтовыми способами: #define CRC8INIT 0x00 #define CRC8POLY 0x18 // X^8+X^5+X^4+X^0 // 0x18 = ( 0x130 >> 1 ) & 0x7F bint crc8_8540( BYTE *data_in, bint bytes ) { BYTE crc = CRC8INIT; bint bit_cnt; register BYTE data; register BYTE feedback_bit; while( bytes-- ) { data = *data_in++; for( bit_cnt=8; bit_cnt; bit_cnt-- ) { feedback_bit = (data^crc) & 0x01; crc >>= 1; data >>= 1; if( feedback_bit ) crc ^= ((CRC8POLY >> 1)|0x80); } } return( crc ); } хоть в железе: //--------------------------------------------------------------------------- // Verilog module containing a synthesizable Dallas CRC8 function // * Polynomial: (8 5 4 0) // * Data width: 8 // * CRC width : 8 // * Mirror //--------------------------------------------------------------------------- module CRC8_8540; function [7:0] nextCRC; input [7:0] Data; input [7:0] CRC; reg [7:0] D; reg [7:0] C; reg [7:0] xCRC; begin D = Data; C = CRC; // Mirror DATA and final CRC xCRC[7] = D[1]^D[3]^D[4]^D[7]^C[7]^C[4]^C[3]^C[1]; xCRC[6] = D[0]^D[2]^D[3]^D[6]^C[6]^C[3]^C[2]^C[0]; xCRC[5] = D[1]^D[2]^D[5]^C[5]^C[2]^C[1]; xCRC[4] = D[0]^D[1]^D[4]^C[4]^C[1]^C[0]; xCRC[3] = D[0]^D[1]^D[4]^D[7]^C[7]^C[4]^C[1]^C[0]; xCRC[2] = D[0]^D[1]^D[4]^D[6]^D[7]^C[7]^C[6]^C[4]^C[1]^C[0]; xCRC[1] = D[0]^D[3]^D[5]^D[6]^C[6]^C[5]^C[3]^C[0]; xCRC[0] = D[2]^D[4]^D[5]^C[5]^C[4]^C[2]; nextCRC = xCRC; end endfunction endmodule Судя по режущим глаз if((i & 0x01)>0) напахать Вы могли в Вашей первой программе где угодно, а не в отцитированных Вами кусочках. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба Так, мимоходом - Собственно говоря, я в С++ только только начал разбиратьсяНе начали - это не С++ :) Похоже это С# (или Java) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nokepp 0 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба В общем вот что у меня получилось: #include <conio.h> #include <stdlib.h> #include <stdio.h> #include <iostream> unsigned char crc8(unsigned char data, unsigned int crc) { unsigned char i=data^crc; crc=0; if(i & 0x01) crc^=0x5e; if(i & 0x02) crc^=0xbc; if(i & 0x04) crc^=0x61; if(i & 0x08) crc^=0xc2; if(i & 0x10) crc^=0x9d; if(i & 0x20) crc^=0x23; if(i & 0x40) crc^=0x46; if(i & 0x80) crc^=0x8c; return crc; } void main (void) { unsigned char a,c=0x00,l=1; a=crc8(c,l); printf("a=0x%x",a); getch(); } В данном примере считает для 0x01.(т.е. l=0x01). Но проблема в том, что считает для значений только до 9. ВСе что выше(10,11,...), выдает уже неверные значения.Мне нужно расширить значение до максимума. Ну например "31FF09". Пока не врублюсь как это сделать.. И еще интересует как сделать чтобы значение можно было вводить в окно консоля...пробовал через using namespace std;но короче он ругается на unsigned char;(прошу прощения за непроффесиональный слэнг) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DpInRock 0 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба Я бы на вашем месте попытался бы разобраться что такое CRC8 вообще. Ибо вы не имеете об этом ни малейшего представления. Т.е. пишите программу, которая слышала звон. Вот рассмотрите данные вам примеры у поинтересуйтесь, чего это оне все имеют некий счетчик байт... И все работают в каком-то цикле... Зачем? Вот в википедии можно подчерпнуть как знания, так и исходные коды на всех языках мира. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nokepp 0 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба Я бы на вашем месте попытался бы разобраться что такое CRC8 вообще. Ибо вы не имеете об этом ни малейшего представления. Т.е. пишите программу, которая слышала звон. Вот рассмотрите данные вам примеры у поинтересуйтесь, чего это оне все имеют некий счетчик байт... И все работают в каком-то цикле... Зачем? Вот в википедии можно подчерпнуть как знания, так и исходные коды на всех языках мира. Сомневаюсь, что на всех языках мира. Я увидел только на СИ...В принципе, как я считаю, алгоритм исчесления я понял. Всю информацию предстваляем как огромное число в бинарном ввиде и делим столбиком, как в школе на используемый полином,ну т.е. не на полином, а на тоже бинарное число, интерпретированное как полином..Остаток от деления и есть искомое crc8. Честно вам скажу, я это делал на бумаге, с небольшими числами. Но когда вижу, такой алгоритм в СИ, почему -то не могу разобраться, что к чему. Я только начал изучать языки и понимаю, что взялся за слишком серьезную задачу для своего уровня программирования. Поэтому прошу помочь мне для ее решения. Ведь чувствую, что близок к завершению Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба ... и делим столбиком... на полином...Остаток от деления и есть искомое crc8. Честно вам скажу, я это делал на бумаге, с небольшими числами. Но когда вижу, такой алгоритм в СИ, почему -то не могу разобраться, что к чему.Вы, наверное, сравниваете "честный" остаток с полученным CRC и удивляетесь, что не совпадают значения? Почитайте что-нибудь по теории вычисления CRC... При вычислении CRC используется двоичная арифметика без учета переносов - тогда сложение/вычитание заменяется операцией "исключающее ИЛИ". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Artem_Petrik 0 31 января, 2011 Опубликовано 31 января, 2011 · Жалоба ... unsigned char crc8(unsigned char data, unsigned int crc) { ... } void main (void) { unsigned char a,c=0x00,l=1; a=crc8(c,l); printf("a=0x%x",a); getch(); } Насколько я вижу, при вызове функции перепутаны местами данные и crc. Понятнее было бы переменную для crc назвать crc (Капитан очевидность ). Я бы написал так: unsigned char crc; unsigned char data = 1; // ну это чтоб от вас не отличаться сильно crc = crc8(data, crc); printf("crc=0x%x",crc); Ну например "31FF09". Пока не врублюсь как это сделать. Приведенное вами значение это 3 байта. Ваша же функция считает crcдля одного байта. Когда нужно посчитать crc для пакета в несколько байт делают так: Допустим нужные нам данные, скажем 8 байт, сложены в unsigned char buf[8]. тогда unsigned char crc = 0; // Начальное значение. В общем случае может быть и не 0, надо смотреть спецификацию. for(i=0;i<8;i++) crc = crc8(buf[i], crc); printf("crc пакета =0x%x",crc); P.S. ну и зачем при обьявлении функции crc сделан unsigned int тоже непонятно. unsigned char надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 1 февраля, 2011 Опубликовано 1 февраля, 2011 · Жалоба Мне попадался полином x^8 + x^2 + x + 1 (CRC-8-Dallas/Maxim) Для него я написал программу, но потом не использовал, так что в работоспособности не поручусь на 100%. /* *********************************************************************** * Расчет циклического избыточного кода CRC для массива сообщения * Используется полином x^8 + x^2 + x + 1 (CRC-8-Dallas/Maxim) * Задается указатель на начало рассчитываемых байтов в массиве, * количество байтов, участвующих в расчете (ровно) * начальный код CRC (если считается не с начала массива), * Для ускорения расчета используется таблица ***********************************************************************/ char calcCRC(char *Ptr, char Num, char CRC) { const char CrcTable[256] = { 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, // 00 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, // 08 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, // 10 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, // 18 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, // 20 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, // 28 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, // 30 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, // 38 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, // 40 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, // 48 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, // 50 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, // 58 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, // 60 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, // 68 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, // 70 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, // 78 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, // 80 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, // 88 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, // 90 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, // 98 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, // a0 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, // a8 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, // b0 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, // b8 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, // c0 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, // c8 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, // d0 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, // d8 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, // e0 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, // e8 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, // f0 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 // f8 }; do CRC = CrcTable[CRC ^ *Ptr++]; while (--Num); return CRC; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dnepr33 0 1 февраля, 2011 Опубликовано 1 февраля, 2011 · Жалоба Сомневаюсь, что на всех языках мира. Я увидел только на СИ...В принципе, как я считаю, алгоритм исчесления я понял. Всю информацию предстваляем как огромное число в бинарном ввиде и делим столбиком, как в школе на используемый полином,ну т.е. не на полином, а на тоже бинарное число, интерпретированное как полином..Остаток от деления и есть искомое crc8. Честно вам скажу, я это делал на бумаге, с небольшими числами. Но когда вижу, такой алгоритм в СИ, почему -то не могу разобраться, что к чему. Я только начал изучать языки и понимаю, что взялся за слишком серьезную задачу для своего уровня программирования. Поэтому прошу помочь мне для ее решения. Ведь чувствую, что близок к завершению Вы не представляете, насколько усложнили себе понимание подсчета CRC ! Посмотрите, как это организуется аппаратно, в виде сдвигового регистра с обратными связями - будете смеяться, насколько все просто ! А для "долбания" указанного вами алгоритма предлагаю взять "нормальные" - из app/notes - и проверить их на ваших тестовых последовательностях - в них могли быть элементарно ошибки, а вы будете долбить головой стену ! ps - имеет значение порядок следования байтов, порядок "сдвига" битов, расположение тетрад в байте ! сделайте сперва работающую правильно модель, а затем бодайтесь с этим конкретным алгоритмом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nokepp 0 7 февраля, 2011 Опубликовано 7 февраля, 2011 · Жалоба Приведенное вами значение это 3 байта. Ваша же функция считает crcдля одного байта. Когда нужно посчитать crc для пакета в несколько байт делают так: Допустим нужные нам данные, скажем 8 байт, сложены в unsigned char buf[8]. тогда unsigned char crc = 0; // Начальное значение. В общем случае может быть и не 0, надо смотреть спецификацию. for(i=0;i<8;i++) crc = crc8(buf[i], crc); printf("crc пакета =0x%x",crc); P.S. ну и зачем при обьявлении функции crc сделан unsigned int тоже непонятно. unsigned char надо. Что-то у меня с данными размеров выше одного байта ничего не получается. Еще компилятор такой дурацкий. Как я понял buf это массив ... i-кол-во байт данных. значит включается счетчик от одного до 8 байт и с каждым прибавлением 1 ,выполняется присваивание. Но не ясно, где же блит данные=( и еще не ясно, как же задействовать команду cin для ввода пакета данных. или для таких задач необходимо задействовать что-то другое? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 7 февраля, 2011 Опубликовано 7 февраля, 2011 · Жалоба Но не ясно, где же блит данные=(Вроде, ясно написаноДопустим нужные нам данные, скажем 8 байт, сложены в unsigned char buf[8]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nokepp 0 7 февраля, 2011 Опубликовано 7 февраля, 2011 · Жалоба Вроде, ясно написано ах!!!не угледел..но все равно например переменной buf я присваиваю значение в 3 байта...и выскакивают какие-то ошибки. ТОчнее мой компилятор, считает по последнему рабочему коду( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Artem_Petrik 0 7 февраля, 2011 Опубликовано 7 февраля, 2011 · Жалоба Как я понял buf это массив ... где же блит данные=( Данные в массиве. В моем примере предполагается что их туда кто-то положил. Откуда они у вас берутся я не знаю. По поводу cin: у вас что, пакет данных кто-то с клавиатуры набивает? Какой кошмар :crying: :) Упс, неуспел :) А как интересно вы "переменной buf я присваиваю значение в 3 байта"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться