Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
По второму пункту: да, синдром будет ненулевой. Но ведь он будет указывать на какой-то один бит. Как определить, что на самом деле была двукратная ошибка?
позволяет исправлять однократные и обнаруживать двукратные ошибки
Расширенный код Хэмминга образуется из совершенного путем добавления общей проверки на четность, т. е. проверочного символа, равного сумме всех символов кода Хэмминга. Код имеет кодовое расстояние, что позволяет исправить все однократные и одновременно обнаружить все двукратные ошибки. Такой режим целесообразен, в частности, в системах передачи информации с обратной связью.
Мое мнение- писать надо о том в, чем разбираешься лучше других.
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
int get_bit(const void *in, size_t n)
{
return (((const uint8_t*)in)[n / CHAR_BIT] & (1 << (n % CHAR_BIT))) != 0;
}
void set_bit(void *out, size_t n, int bit)
{
if (bit)
((uint8_t*)out)[n / CHAR_BIT] |= (1 << (n % CHAR_BIT));
else
((uint8_t*)out)[n / CHAR_BIT] &= ~(1 << (n % CHAR_BIT));
}
void flip_bit(void *out, size_t n)
{
((uint8_t*)out)[n / CHAR_BIT] ^= (1 << (n % CHAR_BIT));
}
size_t encode(void *out, const void *in, size_t in_bits)
{
size_t i, j, k;
unsigned s = 0;
for (i = j = 0; j < in_bits; ++i) {
if ((i + 1) & i) {
if (get_bit(in, j))
s ^= i + 1;
set_bit(out, i, get_bit(in, j));
++j;
}
}
for (k = 1; k < i; k <<= 1) {
set_bit(out, k - 1, s & k);
}
return i;
}
size_t decode(void *out, const void *in, size_t in_bits, unsigned *out_syndrome)
{
size_t i, j;
unsigned s = 0;
for (i = j = 0; i < in_bits; ++i) {
if (get_bit(in, i))
s ^= i + 1;
if ((i + 1) & i) {
set_bit(out, j, get_bit(in, i));
++j;
}
}
*out_syndrome = s;
return j;
}
size_t decode_and_fix(void *out, const void *in, size_t in_bits)
{
unsigned s;
size_t out_bits = decode(out, in, in_bits, &s);
if (s && s <= in_bits && (s & (s - 1))) {
unsigned k;
for (k = 0; 1u << k < s; ++k);
flip_bit(out, s - k - 1);
}
return out_bits;
}
int main()
{
char habr[4] = "habr";
char encoded[5];
char decoded[4];
unsigned s;
size_t i;
size_t encoded_bits = encode(encoded, habr, sizeof(habr) * CHAR_BIT);
size_t decoded_bits = decode(decoded, encoded, encoded_bits, &s);
assert(s == 0);
assert(encoded_bits == sizeof(habr) * CHAR_BIT + 6);
assert(decoded_bits == sizeof(habr) * CHAR_BIT);
assert(memcmp(habr, decoded, sizeof(habr)) == 0);
for (i = 0; i < encoded_bits; ++i) {
flip_bit(encoded, i);
decoded_bits = decode(decoded, encoded, encoded_bits, &s);
decoded_bits = decode_and_fix(decoded, encoded, encoded_bits);
assert(decoded_bits == sizeof(habr) * CHAR_BIT);
assert(memcmp(habr, decoded, sizeof(habr)) == 0);
flip_bit(encoded, i);
}
return 0;
}
Код Хэмминга. Пример работы алгоритма