Перейти к содержанию
    

Все добрый день! необходимо написать программу, простенькую, для расчета контрольной суммы по алгоритму 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 со значением производителя :wacko: . Я писал им support :1111493779: , но они отказываются мне помогать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и, подсчитывая crc в ручную, у меня не совпадало значение моего crc со значением производителя :wacko:
Ну так приведите набор данных и получившуюся у вас и у них crc. По строке if((i & 0x80)>0) crc ^= 0x8c; это должен быть CRC имени Далласа от 1-wire, остальные строки не проверял на правильность.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сразу скажу, что возможно он отличается от привычных всем, ибо этот алгоритм разработан производителями переферийнного устройства и, подсчитывая 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) напахать Вы могли в Вашей первой программе где угодно, а не в отцитированных Вами кусочках.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, мимоходом -

Собственно говоря, я в С++ только только начал разбираться
Не начали - это не С++ :) Похоже это С# (или Java)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем вот что у меня получилось:

 

#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;(прошу прощения за непроффесиональный слэнг)

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы на вашем месте попытался бы разобраться что такое CRC8 вообще. Ибо вы не имеете об этом ни малейшего представления.

Т.е. пишите программу, которая слышала звон.

Вот рассмотрите данные вам примеры у поинтересуйтесь, чего это оне все имеют некий счетчик байт... И все работают в каком-то цикле... Зачем?

Вот в википедии можно подчерпнуть как знания, так и исходные коды на всех языках мира.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы на вашем месте попытался бы разобраться что такое CRC8 вообще. Ибо вы не имеете об этом ни малейшего представления.

Т.е. пишите программу, которая слышала звон.

Вот рассмотрите данные вам примеры у поинтересуйтесь, чего это оне все имеют некий счетчик байт... И все работают в каком-то цикле... Зачем?

Вот в википедии можно подчерпнуть как знания, так и исходные коды на всех языках мира.

 

 

Сомневаюсь, что на всех языках мира. Я увидел только на СИ...В принципе, как я считаю, алгоритм исчесления я понял. Всю информацию предстваляем как огромное число в бинарном ввиде и делим столбиком, как в школе на используемый полином,ну т.е. не на полином, а на тоже бинарное число, интерпретированное как полином..Остаток от деления и есть искомое crc8. Честно вам скажу, я это делал на бумаге, с небольшими числами. Но когда вижу, такой алгоритм в СИ, почему -то не могу разобраться, что к чему. Я только начал изучать языки и понимаю, что взялся за слишком серьезную задачу для своего уровня программирования. Поэтому прошу помочь мне для ее решения. Ведь чувствую, что близок к завершению

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... и делим столбиком... на полином...Остаток от деления и есть искомое crc8. Честно вам скажу, я это делал на бумаге, с небольшими числами. Но когда вижу, такой алгоритм в СИ, почему -то не могу разобраться, что к чему.
Вы, наверное, сравниваете "честный" остаток с полученным CRC и удивляетесь, что не совпадают значения? Почитайте что-нибудь по теории вычисления CRC... При вычислении CRC используется двоичная арифметика без учета переносов - тогда сложение/вычитание заменяется операцией "исключающее ИЛИ".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...

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 (Капитан очевидность :biggrin: ). Я бы написал так:

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 надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне попадался полином 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сомневаюсь, что на всех языках мира. Я увидел только на СИ...В принципе, как я считаю, алгоритм исчесления я понял. Всю информацию предстваляем как огромное число в бинарном ввиде и делим столбиком, как в школе на используемый полином,ну т.е. не на полином, а на тоже бинарное число, интерпретированное как полином..Остаток от деления и есть искомое crc8. Честно вам скажу, я это делал на бумаге, с небольшими числами. Но когда вижу, такой алгоритм в СИ, почему -то не могу разобраться, что к чему. Я только начал изучать языки и понимаю, что взялся за слишком серьезную задачу для своего уровня программирования. Поэтому прошу помочь мне для ее решения. Ведь чувствую, что близок к завершению

Вы не представляете, насколько усложнили себе понимание подсчета CRC !

Посмотрите, как это организуется аппаратно, в виде сдвигового регистра с обратными связями - будете смеяться, насколько все просто !

А для "долбания" указанного вами алгоритма предлагаю взять "нормальные" - из app/notes - и проверить их на ваших тестовых последовательностях - в них могли быть элементарно ошибки, а вы будете долбить головой стену !

ps - имеет значение порядок следования байтов, порядок "сдвига" битов, расположение тетрад в байте !

сделайте сперва работающую правильно модель, а затем бодайтесь с этим конкретным алгоритмом.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приведенное вами значение это 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 для ввода пакета данных. или для таких задач необходимо задействовать что-то другое?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но не ясно, где же блит данные=(
Вроде, ясно написано
Допустим нужные нам данные, скажем 8 байт, сложены в unsigned char buf[8].

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде, ясно написано

 

ах!!!не угледел..но все равно например переменной buf я присваиваю значение в 3 байта...и выскакивают какие-то ошибки. ТОчнее мой компилятор, считает по последнему рабочему коду(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как я понял buf это массив ...  где же блит данные=(

 

Данные в массиве. В моем примере предполагается что их туда кто-то положил. Откуда они у вас берутся я не знаю. По поводу cin: у вас что, пакет данных кто-то с клавиатуры набивает? Какой кошмар :crying:  :)

 

Упс, неуспел :)

А как интересно вы "переменной buf я присваиваю значение в 3 байта"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...