Russian Qt Forum
Май 03, 2024, 20:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [Решено]QByteArray подсчет контрольной суммы  (Прочитано 10346 раз)
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 = СС

Подскажите как реализовать подобный алгоритм?
Есть ли какое-то название у этого алгоритма подсчета контрольной суммы?
« Последнее редактирование: Август 29, 2014, 12:46 от TestUser013 » Записан
Bepec
Гость
« Ответ #1 : Август 28, 2014, 16:41 »

Вы его только что реализовали пусть и в псевдокоде.
Записан
TestUser013
Гость
« Ответ #2 : Август 28, 2014, 16:50 »

Я не пойму как суммировать байты. И не знаю как разбить полученную сумму на 2 байты...
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #3 : Август 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
 
 
Записан
twp
Гость
« Ответ #4 : Август 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 );
 
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #5 : Август 28, 2014, 19:14 »

Не думаю что это правильно, ибо подразумевает порядок байт LittleEndian и может быть не портабельно для BigEndian.
ну, во-первых : где вы видели живые BigEndian архитектуры ?
во-вторых : в контексте задачи  - это не существенно.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4349



Просмотр профиля
« Ответ #6 : Август 28, 2014, 19:20 »

ну, во-первых : где вы видели живые BigEndian архитектуры ?
Некоторые Армы могут и так и так - как инициализируешь, так и будет. Другое дело, что в big их инициализируют не часто. Улыбающийся
 
Записан
TestUser013
Гость
« Ответ #7 : Август 28, 2014, 20:14 »

Спасибо. Все работает Улыбающийся
А можете объяснить простыми словами как работают эти конструкции? Не совсем понимаю... Хочется еще понимания, не только готового результата Улыбающийся

unsigned char c = unsigned char(sum & 0xFF);
unsigned char c =   ((unsigned char*)(&sum))[0];
« Последнее редактирование: Август 28, 2014, 20:20 от TestUser013 » Записан
Alexu007
Гость
« Ответ #8 : Август 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. Если и тут будет непонятно - объясним.
Записан
TestUser013
Гость
« Ответ #9 : Август 29, 2014, 09:41 »

Кажется понял. Сначала в переменной у будет 2В. Фактически мы берем только последние 2 знака. Если б было y = x & 0xFF00; , то в переменной у оказалось бы первые 2 байта 1А.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #10 : Август 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)
Записан
Bepec
Гость
« Ответ #11 : Август 29, 2014, 12:05 »

А ссылочка то битая Улыбающийся
Записан
Alexu007
Гость
« Ответ #12 : Август 29, 2014, 13:46 »

Если б было y = x & 0xFF00; , то в переменной у оказалось бы первые 2 байта 1А.
Не совсем так. 0x1A2B & 0xFF00 = 0x1A00 - то есть десятичное 6656, не думаю что это тот результат, который вам нужен. Чтобы в переменной оказалось 001А, нужно сдвинуть вправо на 8 бит операцией >> 8
Записан
vizir.vs
Гость
« Ответ #13 : Август 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 - какая разница? От того, что я буду слева направо складывать или справа налево разницы ни какой. Мы все равно разбиваем число на байты и сумма этих байт в обоих системах будет одинаковой.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #14 : Август 29, 2014, 20:59 »

Откройте калькулятор, входящий в состав win7. Там есть все унарные операции. А под основным таблом имеется представление числа по битам с разделением по 4 бита.
& - And
| - Or
<< - Lsh
>> - Rsh
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.38 секунд. Запросов: 24.