Контрольная сумма Флетчера для группы байтов произвольной длины
Я пытаюсь реализовать функцию для вычисления 8-битной контрольной суммы Флетчера для области памяти переменной длины, идея состоит в том, что я мог бы передать 2-байтовый короткий или 2-килобайтный массив и использовать ту же функцию. Я только исследовал это сегодня, поэтому я определенно не эксперт по алгоритмам контрольных сумм или арифметике указателей, и мой код почти наверняка полон ошибок.
В основном моя стратегия состоит в том, чтобы передать указатель на адрес первого байта в группе, а также размер области памяти для сканирования, и, пока размер всегда равен size of (передаваемый объект), он будет действительный. Я мог бы вычислить size of внутри функции, чтобы избежать потенциальных ошибок, но я думаю, что мне пришлось бы ограничить принятый тип конкретным типом.
Теперь, насколько я понимаю, *(ptr + i) должен вернуть значение, расположенное в i-м байте после адреса ptr. Я не делал ничего подобного раньше, поэтому, возможно, я неправильно понял то, что я прочитал.
uint8_t fletcher_8(void *data, uint size){
data = (uint8_t *)data; // Recast pointer as uint8_t*
uint8_t sum1 = 0;
uint8_t sum2 = 0; // Initialise variables for algorithm
for (int i =0; i < size; i++){
sum1 += *(data + i); // get the value of the ith byte after the data pointer's address
sum2 += sum1;
}
sum1 %= 16; // modulo the first sum
sum1 << 4; // shift lower four bits to the upper four bits
sum2 %= 16; // modulo the second sum
return sum1 + sum2; // add both sums (highest four bits are sum1, lower four bits are sum2
}
Если бы я полностью помешался, и есть какой-то более простой способ реализовать то, что я пытаюсь сделать, мне бы очень хотелось это услышать!
РЕДАКТИРОВАТЬ:
Я специально спрашиваю о реализации C++, но приведенный выше код также может быть псевдокодом. Я больше всего хочу знать, правильн ли мой подход больше всего на свете.
1 ответ
Ваша первая версия была лучше, чем вторая.
некоторые ошибки во второй версии:
data
не должно быть типаvoid *
, иначе*(data + i)
это ошибка времени компиляцииdata = (uint8_t *)data;
ничего не делает.sum1 << 4;
пропускает=
делать что-либо:sum1 <<= 4;
i
а такжеsize
должен быть того же типа. я предпочитаюsize_t
потому что это типsizeof
возвращается.https://en.wikipedia.org/wiki/Fletcher%27s_checksum говорит, что старшие биты должны быть
sum2
ваши биты изsum1
,
Я бы так написал
uint8_t fletcher_8(uint8_t *data, size_t size){
uint8_t sum1 = 0;
uint8_t sum2 = 0;
for (size_t i = 0; i < size; i++){
sum1 += data[i];
sum2 += sum1;
}
return (sum1 & 0xF) | (sum2 << 4);
}
или же
uint8_t fletcher_8(uint8_t *data, size_t size){
uint8_t sum1 = 0;
uint8_t sum2 = 0;
while (size--){
sum1 += *data++;
sum2 += sum1;
}
return (sum1 & 0xF) | (sum2 << 4);
}