Кодирование Хэмминга может быть реализовано с помощью битовых манипуляций.Вероятно, это даже проще, чем со строкой.Вот несколько идей по реализации.
Схема алгоритма кодирования Хэмминга следующая:
input_val is a long int to encode
output_val_is the long int result
for s in 0..5
count number of bits in input_val whose position has bit s set
add to output_val the parity of this count
add next 2^s bits from input_val to output_val
Действительно, есть две проблемы: получение четности определенного набора битов и создание выходных данных.с битовыми сдвигами.
Подсчет установленных битов по заданному шаблону *
Для кодирования Хэмминга необходимо вычислить четность на подмножестве битов (шаблон).Шаблоны: 010101010101 ... 01 для первого шага, 001100110 ... 00110 для второго шага и т. Д. И могут быть закодированы в массив mask
, индексированный по номеру шага.mask [0] = 0x5555555555555555, mask [1] = 0x6666666666666666, mask [2] = 0xf0f0f0f0f0f0f0f0, mask [3] = 0xff00ff00ff00ff00 и т. д.
Чтобы получить эту четность, проще считать и подсчитать числочтобы получить младший балл этого подсчета.В Java есть функция, которая дает число битов в целом числе.Следовательно, единственной требуемой здесь операцией является
count=Integer.bitcount(input_val & masks[s]) ;
, где s - номер этапа вычисления.
Затем необходимо добавить к выводу count & 0x1
, чтобы добавить четность счета.
Добавление бита к целому числу
Оно тесно связано с количеством битов в вашем входном и выходном размере значения.Для простоты я предполагаю, что обе ваши данные могут быть закодированы на 64 битах.Это означает, что у вас есть 6 битов четности, и что ваши входные данные являются только частью вашей переменной, и что 6 MSB input_data равны нулю.
Чтобы добавить младший бит целого числа v
к output_val
проще добавить его в позиции результата MSB и сдвинуть его вправо.После добавления 64 битов все на своем месте.Обратите внимание, что output_val должен быть без знака, чтобы избежать арифметического смещения вправо.
Итак, чтобы добавить младший бит v к output_val, нужно выполнить операцию
output_val = (output_val >> 1) | (v<< 63);
v << 63 извлечьLSB и поставить его в положение MSB.ИЛИ добавляет к смещенному результату. </p>
Чтобы добавить несколько битов (например, k), можно использовать
output_val = (output_val >> k) | (v<< (64-k));
Так что окончательная реализация (для улучшения) будет выглядеть примерно так:
input_queue = input_val;
output_val = 0;
for (s=0; s<6;s++) {'
count=Integer.bitcount(input_val & masks[s]) ; // compute parity
output_val = (output_val >> 1) | (count << 63);// add parity to output
output_val = (output_val >> (1<<s)) | (input_queue << (64-(1<<s));
// add 2^s LSB of input to output
input_queue >>=(1<<s); // suppress 2^s bits form input_queue
}