Borgir |
Отправлено: 28.08.2003, 10:32 |
|
Не зарегистрирован
|
Возникла у меня необходимость подсчитывать CRC в программе. А как это реализовать не знаю. То есть есть у меня некая исходная AnsiString, и надо посчитать ее CRC и соответственно выдать результат (хоть в AnsiString, хоть в CHAR). Нашел на форуме по Дельфи процедурку, но конвертировать паскалевский текст в С++ оказалось не так просто (например я не знаю С++сный аналог паскалевской функции Ord().
Может кто поможет. Заранее спасибо. |
|
Ermakov |
Отправлено: 29.08.2003, 06:16 |
|
Не зарегистрирован
|
Нашел кусок который когдато делал
unsigned int CRC16(int Count,char *Ptr)
{
unsigned int Data;
int CRC=0xffff;
while(Count)
{
Data=*Ptr;
CRC^=Data;
for(int j=0;j<8;j++) // побитная обработка
{
if(CRC&1)
{CRC>>=1;
CRC^=0xa001;}
else
{CRC>>=1;}
}
Ptr++;
Count--;
}
return CRC;
}
код конечно ни самый лучший, на входе исло байт которые надо подсчитать и ссылка на массив байт |
|
Borgir |
Отправлено: 29.08.2003, 07:10 |
|
Не зарегистрирован
|
Функция хорошая. Только подскажите, как полученное число преобразовать в ASCII, чтобы можно было добавить его к исходной строке и послать в качестве команды некоему внешнему устройству по COM-порту? |
|
Ermakov |
Отправлено: 29.08.2003, 07:30 |
|
Не зарегистрирован
|
ну если надо просто int в ASCII то функция itoa() преобразует. В билдере IntToStr() есть.
Если я правильно понял вопрос |
|
Asher |
Отправлено: 29.08.2003, 08:22 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Преобразование из AnsiString AStr в массив байт *CStr
CODE | AnsiString AStr = "ATDP123456";
char *CStr = AStr.c_str();
|
Добавление контрольной суммы к строке
CODE | char CRC = 33;
AStr += CRC;
|
P.S. Запрсто можно нарваться на управляющий символ или на NULL, поэтому для контрольной суммы все-таки наверное надежнее делать IntToHex(CRC, 2) чтобы получать результат стандартной длины.
Тогда получим:
CODE | char CRC = 33;
AStr += IntToHex(CRC, 2);
|
|
|
Borgir |
Отправлено: 29.08.2003, 11:42 |
|
Не зарегистрирован
|
Что-то видимо я совсем чайник, но у меня ничего не получается. Наверно я не так спрашиваю. Скажем так. Есть некая строка символов. Я считаю ее CRC этой функцией, на выходе которой целое число. Но я точно знаю, что в качестве CRC к строке должны добавляться 2 символа. Как мне их получить? то что вы тут привели выше не помогает. Вот конкретный пример (я его выловил шпионом СОМ-порта):
исходная строка "#91200000C", при этом CRC "F2". Как мне его получить? Следуя вашим рекомендациям я получал совершенно другое
или еще такой вопрос. Беру я например первый символ исходной строки, мне надо получить его ASCII-код. Как это сделать? Ведь точно должна быть такая функция. И обратная должна быть. |
|
Kot |
Отправлено: 29.08.2003, 12:11 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 6
|
Так а зачем поток с порта преобразовывать в АСКИ.
Во-вторых полином использованный в данной функции 0xa001 а может применятся и другой. Данная функция была написана для работы с протоколом ModBus.
Что у тебя за железка раскажи по подробнее. |
|
Asher |
Отправлено: 29.08.2003, 13:25 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
QUOTE | Беру я например первый символ исходной строки, мне надо получить его ASCII-код. Как это сделать? Ведь точно должна быть такая функция. И обратная должна быть. |
Считай что тип char это и есть символы в кодах ASCII если так надо
Преобразование из AnsiString AStr в массив байт *CStr
CODE |
AnsiString AStr = "ATDP123456";
char *CStr = AStr.c_str(); |
CStr[0] — код ASCII первого символа, CStr[1] второго, и так далее до CStr[AStr.Length()-1]
Если символ хранящийся в char прибавляешь к строке в AnsiString, как
CODE | char CRC = 33;
AStr += CRC; |
то он сам и переведется. Если хочешь сам, то
AStr += (AnsiString)CRC;
Если тебя смущает что отладчик при наведении на char пишет буквы — ну попробуй переписать из char в int и смотри на цифры, сверяясь со своей таблицей ASCII.
А чтобы получить конкретный правильный код CRC надо бы знать конкретный алгоритм. CRC это не имя собственное
Отредактировано Asher — 29/08/2003, 15:28
|
|
Nick |
Отправлено: 31.08.2003, 06:42 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
QUOTE (Borgir @ 28/08/2003, 11:34) | Не знаю С++сный аналог паскалевской функции Ord().
|
Если те это поможет:
Ord() — насколько я помню это код символа.
В C++ он не нужен т.к.
char a = 'a';
int i = 1;
char b = a + i; // = 'b'
Можно легко сложить два char
i = a+b;
в паскале пришлось бы
i := Ord(a)+Ord(;
|
|
Borgir |
Отправлено: 02.09.2003, 06:26 |
|
Не зарегистрирован
|
Спасибо, всем за участие в обсуждении. Я уже во всем разобрался — просто нашел функцию в другой программе. Там немного более сложный алгоритм, чем тот, что был приведен здесь в примере, но суть таже самая. Если кому интересно могу привести текст этой функции. |
|
FoxVID |
Отправлено: 02.01.2004, 16:20 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 29
|
Уважаемые, однако, подсчет контрольной суммы зависит от конкретной реализации. Может быть просто суммирование всех байт, может быть "инкремент инверсии суммы байтов" *(Меркурий112Ф) и т.д.
Я уже не говорю о подсчете контрольной суммы в виде CRC-8, CRC-16, CRC-32 и т.д.
Нужно знать для какого аппарата и по какому алгоритму реализован подсчет контрольной суммы. |
|
DVD |
Отправлено: 21.05.2004, 09:42 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 33
|
А есть ли какой-нибудь компонент для подсчета CRC любых файлов? Даже очень больших. Ведь ручками это затруднительно делать. |
|
exp |
Отправлено: 21.05.2004, 21:24 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Дааааа, дожили. Вот так мозги и ветшают.
Сначала просим компонентик, потом исходники проги, а потом мозги совсем перестанут работать. ((
По сути твоя задача состоит:
1) В представлении сообщения в двоичном виде виде
2) Выборе образующего полинома
3) Реализации деления* (или умножения**) по модулю 2.
*4) В случае деления исходного сообщения нужно добавить полученный остаток от деления в конец сообщения и отправить его.
**5) В случае умножения сообщения на образующий полином просто отправить полученный резулютат.
6) При получении сообщения на приемнике — разделить принятое сообщение на образующия полином и проверить остаток от деления на равенство нулю. В случае этого равенства считать, что принятое сообщение пришло без ошибок.
Вот и все.
//Кстати лично мне больше нравится вариант с умножением.
|
|