Контрольная сумма Флетчера для группы байтов произвольной длины

Я пытаюсь реализовать функцию для вычисления 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);
}
Другие вопросы по тегам