Russian Qt Forum

Qt => Вопросы новичков => Тема начата: TestUser013 от Август 28, 2014, 16:36



Название: [Решено]QByteArray подсчет контрольной суммы
Отправлено: TestUser013 от Август 28, 2014, 16:36
Здравствуйте.
Есть 2 массива byte1 и byte2 типа QByteArray.

Надо подсчитать контрольную сумму этих 2-х массивов вместе.
Контрольная сумма считается как сумма всех байт этих массивов. И в случаи, если сумма получается больше чем 255 разбить полученное число на байты и опять просуммировать их.

Например:
byte1 = [0xFD, 0xFD, 0xFD]
byte1 = [0xF0, 0xF0, 0xF0]
Сумма = 0xFD + 0xFD + 0xFD + 0xF0 + 0xF0 + 0xF0 = 5С7
Далее полученную сумму 5С7 надо разбить на байта 0х05 и 0хС7 и опять просуммировать их.
Сумма = 0х05 + 0хС7 = СС

Подскажите как реализовать подобный алгоритм?
Есть ли какое-то название у этого алгоритма подсчета контрольной суммы?


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: Bepec от Август 28, 2014, 16:41
Вы его только что реализовали пусть и в псевдокоде.


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: TestUser013 от Август 28, 2014, 16:50
Я не пойму как суммировать байты. И не знаю как разбить полученную сумму на 2 байты...


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: alex312 от Август 28, 2014, 18:35
Код
C++ (Qt)
int sum = 0;
for(int i = 0;i < byte1.size(); ++i)
    sum+= (unsigned char)byte1[i];
....
unsigned char c =   ((unsigned char*)(&sum))[0] ; //получаем первый байт у int'a
 
 


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: twp от Август 28, 2014, 19:03
Код
C++ (Qt)
....
unsigned char c =   ((unsigned char*)(&sum))[0] ; //получаем первый байт у int'a
 

Не думаю что это правильно, ибо подразумевает порядок байт LittleEndian и может быть не портабельно для BigEndian.
ИМХО надежней
Код
C++ (Qt)
unsigned char c = unsigned char(sum & 0xFF);
 
Кроме того контрольные суммы можно получить функциями:
Код
quint16 qChecksum ( const char * data, uint len );
uint qHash ( const QByteArray & key );
 


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: alex312 от Август 28, 2014, 19:14
Не думаю что это правильно, ибо подразумевает порядок байт LittleEndian и может быть не портабельно для BigEndian.
ну, во-первых : где вы видели живые BigEndian архитектуры ?
во-вторых : в контексте задачи  - это не существенно.


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: Old от Август 28, 2014, 19:20
ну, во-первых : где вы видели живые BigEndian архитектуры ?
Некоторые Армы могут и так и так - как инициализируешь, так и будет. Другое дело, что в big их инициализируют не часто. :)
 


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: TestUser013 от Август 28, 2014, 20:14
Спасибо. Все работает :)
А можете объяснить простыми словами как работают эти конструкции? Не совсем понимаю... Хочется еще понимания, не только готового результата :)

unsigned char c = unsigned char(sum & 0xFF);
unsigned char c =   ((unsigned char*)(&sum))[0];


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: Alexu007 от Август 28, 2014, 23:24
Код
C++ (Qt)
   quint32 x = 0x1A2B;
   quint32 y;
 
   y = x & 0x00FF;
   ui->label_1->setText(QString::number(y, 16));
 
   y = x >> 8;
   ui->label_2->setText(QString::number(y, 16));

Не бойся экспериментировать, напиши например вот такой код и посмотри чему равно y. Если и тут будет непонятно - объясним.


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: TestUser013 от Август 29, 2014, 09:41
Кажется понял. Сначала в переменной у будет 2В. Фактически мы берем только последние 2 знака. Если б было y = x & 0xFF00; , то в переменной у оказалось бы первые 2 байта 1А.


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: __Heaven__ от Август 29, 2014, 10:51
https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: Bepec от Август 29, 2014, 12:05
А ссылочка то битая :)


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: Alexu007 от Август 29, 2014, 13:46
Если б было y = x & 0xFF00; , то в переменной у оказалось бы первые 2 байта 1А.
Не совсем так. 0x1A2B & 0xFF00 = 0x1A00 - то есть десятичное 6656, не думаю что это тот результат, который вам нужен. Чтобы в переменной оказалось 001А, нужно сдвинуть вправо на 8 бит операцией >> 8


Название: Re: QByteArray подсчет контрольной суммы
Отправлено: vizir.vs от Август 29, 2014, 16:45
Код
C++ (Qt)
....
unsigned char c =   ((unsigned char*)(&sum))[0] ; //получаем первый байт у int'a
 

Не думаю что это правильно, ибо подразумевает порядок байт LittleEndian и может быть не портабельно для BigEndian.
ИМХО надежней
Код
C++ (Qt)
unsigned char c = unsigned char(sum & 0xFF);
 
Кроме того контрольные суммы можно получить функциями:
Код
quint16 qChecksum ( const char * data, uint len );
uint qHash ( const QByteArray & key );
 
LittleEndian|BigEndian - какая разница? От того, что я буду слева направо складывать или справа налево разницы ни какой. Мы все равно разбиваем число на байты и сумма этих байт в обоих системах будет одинаковой.


Название: Re: [Решено]QByteArray подсчет контрольной суммы
Отправлено: __Heaven__ от Август 29, 2014, 20:59
Откройте калькулятор, входящий в состав win7. Там есть все унарные операции. А под основным таблом имеется представление числа по битам с разделением по 4 бита.
& - And
| - Or
<< - Lsh
>> - Rsh


Название: Re: [Решено]QByteArray подсчет контрольной суммы
Отправлено: Fregloin от Август 31, 2014, 09:47
советую автору темы почитать про битовые операции в с++, и сразу все станет на свои места.


Название: Re: [Решено]QByteArray подсчет контрольной суммы
Отправлено: Bepec от Август 31, 2014, 09:57
Почитать бессмысленно. Надо пробовать. Тогда и руки запомнят, и легче будет.