Кодирование Хэмминга

108
30 декабря 2021, 00:50

Срочно нужна помощь. Алгоритм кодирования (он несложный) доступен по ссылкам:

  • Вычисление
  • Статья на Хабре с алгоритмом

Мне необходимо реализовать цикл/метод/что угодно, который будет вычислять контрольный бит.

Вычисление бита выглядит примерно так: если, к примеру, мы вычисляем третий контрольный бит, его порядковый номер равен (2^3 - 1) (т.к. массив начинается с нуля), а равен бит сумме (по модулю 2) 2^3 битов начиная с члена (2^3 - 1) через 2^3 бит (в статье на Хабре всё подробно описано).
Например, длина сообщения равна 8, первый бит вычисляется ([0] + [2] + [4] + [6] + [8] + [10]) % 2 (закодированное сообщение становится длиннее на Log2(длина исх. сообщения).

Прошу помочь примерным алгоритмом / псевдокодом / кодом на c#.

Мне удалось пока только реализовать заполнение контрольных битов нулями перед их вычислением.

Пример:
Ввод: 10011010
Вывод: 011100101010
При условии корректной работы программы, но на данный момент работает следующим образом:
Ввод: 10011010
Вывод: 0 0 1 7 0 0 1 56 1 0 1 0

static void Main(string[] args)
{
    Console.Write("Введите сообщение: ");
    string inMessage = Console.ReadLine();
    byte[] codedMessage = new byte[(int)(inMessage.Length + Math.Ceiling(Math.Log(inMessage.Length, 2)) + 1)];
    bool wasCodeBit;
    int count = 0;
    for (int i = 0; i < codedMessage.Length; i++)
    {
        wasCodeBit = false;
        for (int j = 0; j < Math.Ceiling(Math.Log(inMessage.Length, 2)) + 1; j++)
        {
            if (i == Math.Pow(2, j) - 1)
            {
                codedMessage[i] = 0;
                wasCodeBit = true;
            }
        }
        if (!wasCodeBit)
        {
            codedMessage[i] = byte.Parse(inMessage[count].ToString());
            count++;
        }
    }
    for (int i = 1; i <= Math.Ceiling(Math.Log(inMessage.Length, 2)); i++) //сложение необходимых битов в контрольный
    {
        for(int j = 0; j < codedMessage.Length; j++)
        {
            if ((j - i + 1) / i % 2 == 0)
                codedMessage[(int)Math.Pow(2, i) - 1] += codedMessage[i];
        }
    }
    for (int i = 0; i <= Math.Ceiling(Math.Log(inMessage.Length, 2)); i++) //окончание сложения по модулю 2
        codedMessage[(int)Math.Pow(2, i) - 1] %= 2;
    foreach (int x in codedMessage)
        Console.Write($"{x} ");
}
Answer 1

Накатал примерный алгоритм. По крайней мере на ваших данных отрабатывает.

void Encode()
{   
    var messageArray = new BitArray(new byte[] { (byte)0b01011001});
    int messageInd = 0;
    int retInd = 0;
    int controlIndex = 1;
    var retArray = new BitArray(messageArray.Length + 1 + (int)Math.Ceiling(Math.Log2(messageArray.Length)));   
    while (messageInd < messageArray.Length)
    {
        if (retInd + 1 == controlIndex)
        {           
            retInd++;
            controlIndex = controlIndex * 2;
            continue;
        }
        retArray.Set(retInd, messageArray.Get(messageInd));
        messageInd++;
        retInd++;
    }
    retInd = 0;
    controlIndex = 1 << (int)Math.Log2(retArray.Length);
    while (controlIndex > 0)
    {
        int c = controlIndex - 1;
        int counter = 0;
        while (c < retArray.Length)
        {
            for (int i = 0; i < controlIndex && c < retArray.Length; i++)
            {
                if (retArray.Get(c))
                    counter++;
                c++;
            }
            c += controlIndex;
        }
        if (counter % 2 != 0) retArray.Set(controlIndex - 1, true);
        controlIndex = controlIndex / 2;
    }
    Console.WriteLine("input");
    for (int i = 0; i < messageArray.Length; i++)
    {
        Console.Write($"{(messageArray.Get(i) ? 1 : 0)}   ");
    }
    Console.WriteLine();
    Console.WriteLine("output");
    for (int i = 0; i < retArray.Length; i++)
    {
        Console.Write($"{(retArray.Get(i) ? 1 : 0)}   ");
    }
}

Вывод

input
1   0   0   1   1   0   1   0   
output
0   1   1   1   0   0   1   0   1   0   1   0   
READ ALSO
Все аудео дорожки MediaElement - mp4

Все аудео дорожки MediaElement - mp4

Может кто подсказать? Как в WPF заставить MediaElement воспроизводить все аудио дорожки из видеоЯ открываю видео (кусок моего геймплея) но из звука...

83
Распарсить таблицу excel через C#

Распарсить таблицу excel через C#

У меня есть файл, из которого необходимо заполнить базу данныхСтруктура файла сложная(например, значение ячейки С6 зависит от Company name1, Type1,...

223
Что означает интструкция ret(il код)

Что означает интструкция ret(il код)

Имеется такая строчка в методе на il: "IL_0007: ret"Что это значит ? (Понятно, что это связано с окончанием метода, но как конкретно)

230
обработка всех строк в DataGridView

обработка всех строк в DataGridView

Пытаюсь по нажатию кнопки обработать все строки в гридеВ моем случае есть грид с сообщениями

240