Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Sabelnikov_RGR3_2_3_CodingTheory.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
779.45 Кб
Скачать
  1. Исходный код программы

  1. Классы, представляющие алфавит

public class Symbol

{

public char Char { get; set; }

public int Code { get; set; }

}

public class Alphabet

{

private List<Symbol> list = new List<Symbol>();

public List<Symbol> Content { get { return list; } set { list = value; } }

public string Header { get; set; }

public void AddSymbol(Symbol sym)

{

list.Add(sym);

}

}

  1. Класс, реализующий хранение и вывод информации на форму

public class Result : INotifyPropertyChanged

{

private Symbol _symb;

private string _hammingCode;

private string _hammingCodeEditable;

private string _controlNumber;

private string _correctedHammingCode;

private char _decodedSymbol;

private int _correctedBit;

private string _decodedCode;

public Symbol Symb

{

get { return _symb; }

set { _symb = value; NotifyPropertyChanged("Symb"); }

}

public string HammingCode

{

get { return _hammingCode; }

set { _hammingCode = value; NotifyPropertyChanged("HammingCode"); }

}

public string HammingCodeEditable

{

get { return _hammingCodeEditable; }

set { _hammingCodeEditable = value; NotifyPropertyChanged("HammingCodeEditable"); }

}

public string ControlNumber

{

get { return _controlNumber; }

set { _controlNumber = value; NotifyPropertyChanged("ControlNumber"); }

}

public string CorrectedHammingCode

{

get { return _correctedHammingCode; }

set { _correctedHammingCode = value; NotifyPropertyChanged("CorrectedHammingCode"); }

}

public string DecodedCode

{

get { return _decodedCode; }

set { _decodedCode = value; NotifyPropertyChanged("DecodedCode"); }

}

public char DecodedSymbol

{

get { return _decodedSymbol; }

set { _decodedSymbol = value; NotifyPropertyChanged("DecodedSymbol"); }

}

public int CorrectedBit

{

get { return _correctedBit; }

set { _correctedBit = value; NotifyPropertyChanged("CorrectedBit"); }

}

// for auto updating

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String propertyName)

{

PropertyChangedEventHandler handler = PropertyChanged;

if (null != handler)

{

handler(this, new PropertyChangedEventArgs(propertyName));

}

}

}

  1. Главный класс логики

public class BusinessLayer

{

private List<Alphabet> alphabethList = new List<Alphabet>();

private List<List<int>> hammingMatrix;

private bool allowHamming = false;

private List<Result> results;

public List<Result> Results

{

get { return results; }

}

public bool AllowHamming

{

get { return allowHamming; }

}

public List<Alphabet> AlphabethList

{

get { return alphabethList; }

}

public Alphabet SelectedAlphabet

{

get { return selectedAlphabet; }

set { selectedAlphabet = value; }

}

public BusinessLayer()

{

InsertAlphabets();

allowHamming = false;

selectedAlphabet = alphabethList[0];

}

private void InsertAlphabets()

{

var alphabet = new Alphabet {Header = "Roman (a-n)"};

for (var i = 'a'; i <= 'n'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - 'a') });

}

alphabethList.Add(alphabet);

alphabet = new Alphabet { Header = "Roman (a-z)" };

for (var i = 'a'; i <= 'z'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - 'a') });

}

alphabethList.Add(alphabet);

alphabet = new Alphabet { Header = "Roman (o-z)" };

for (var i = 'o'; i <= 'z'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - 'o') });

}

alphabethList.Add(alphabet);

alphabet = new Alphabet {Header = "Cyrillic (а-м)"};

for (var i = 'а'; i <= 'м'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - 'а') });

}

alphabethList.Add(alphabet);

alphabet = new Alphabet { Header = "Cyrillic (о-я)" };

for (var i = 'о'; i <= 'я'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - 'о') });

}

alphabethList.Add(alphabet);

alphabet = new Alphabet { Header = "Cyrillic (а-я)" };

for (var i = 'а'; i <= 'я'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - 'а') });

}

alphabethList.Add(alphabet);

alphabet = new Alphabet { Header = "Numbers (0-9)" };

for (var i = '0'; i <= '9'; i++)

{

alphabet.AddSymbol(new Symbol() { Char = i, Code = (i - '0') });

}

alphabethList.Add(alphabet);

}

private Alphabet selectedAlphabet = null;

public void StartAlgo(bool wholeAlphabet, int selectedAlph, char symbol = ' ')

{

if (wholeAlphabet)

{

selectedAlphabet = alphabethList[selectedAlph];

}

else

{

// find Symbol

var symb = new Symbol();

foreach (var cur in alphabethList[selectedAlph].Content)

{

if (cur.Char == symbol)

{

symb = new Symbol { Char = cur.Char, Code = cur.Code };

}

}

// save symbol

selectedAlphabet = new Alphabet

{

Content = new List<Symbol> { symb },

Header = "Standalone symbol"

};

}

allowHamming = true;

results = new List<Result>();

foreach (var cur in selectedAlphabet.Content)

{

results.Add(new Result {Symb = cur});

}

CodeParameters.SymbolCodeLength = Convert.ToInt32(Math.Ceiling(Math.Log(alphabethList[selectedAlph].Content.Count, 2)));

var codeLength = CodeParameters.SymbolCodeLength;

var tmpStr = "";

for (var i = 0; i < codeLength; i++)

{

tmpStr += "1";

}

CodeParameters.HammingCodeLength = ToHammingCode(tmpStr).Length;

}

private string ToHammingCode(string code)

{

var res = code;

for (var i = 0; i < res.Length; i++)

{

var power = Math.Log(i + 1, 2);

if (Math.Abs(Math.Floor(power) - power) < 0.0000001)

{

res = res.Substring(0, i) + "0" + res.Substring(i);

}

}

return res;

}

private List<int> GetHammingCorrectingIndexes(int length)

{

var res = new List<int>();

for (var i = 0; i < length; i++)

{

var power = Math.Log(i + 1, 2);

if (Math.Abs(Math.Floor(power) - power) < 0.0000001)

{

res.Add(i);

}

}

return res;

}

public void RunHamming()

{

var correctingBits = CodeParameters.HammingCodeLength - CodeParameters.SymbolCodeLength;

// fill hamming matrix

hammingMatrix = new List<List<int>>();

for (var i = 0; i < correctingBits; i++)

{

var row = new List<int>();

for (var j = 1; j <= CodeParameters.HammingCodeLength; j++)

{

row.Add((j & (1<<i)) == 0 ? 0 : 1);

}

hammingMatrix.Add(row);

}

var conv = new IntegerToBinaryConverter();

var curIndex = 0;

foreach (var symbol in selectedAlphabet.Content)

{

var symbolCode = conv.Convert(symbol.Code, null, "Symbol", null).ToString();

var hammingCode = ToHammingCode(symbolCode);

var hammingBits = "";

for (var k = 0; k < correctingBits; k++)

{

var sum = 0;

for (var m = 0; m < CodeParameters.HammingCodeLength; m++)

{

if (hammingMatrix[k][m].ToString() == hammingCode[m].ToString() && hammingCode[m].ToString() == "1") sum++;

}

hammingBits += (sum%2 == 0) ? "0" : "1";

}

var bitIndex = 0;

foreach (var hammingCorrectingIndex in GetHammingCorrectingIndexes(hammingCode.Length))

{

hammingCode = hammingCode.Substring(0, hammingCorrectingIndex) + hammingBits[bitIndex] + ((hammingCorrectingIndex + 1 < hammingCode.Length) ? hammingCode.Substring(hammingCorrectingIndex + 1) : "");

bitIndex++;

}

Results[curIndex].HammingCode = hammingCode;

Results[curIndex].HammingCodeEditable = hammingCode;

curIndex++;

}

}

public void RunDecode()

{

var correctingBits = CodeParameters.HammingCodeLength - CodeParameters.SymbolCodeLength;

var conv = new IntegerToBinaryConverter();

var curIndex = 0;

foreach (var result in Results)

{

if (result.HammingCodeEditable.Length != CodeParameters.HammingCodeLength)

{

MessageBox.Show("Hey! The length of hamming code is wrong!");

return;

}

var hammingBits = "";

var hammingCode = result.HammingCodeEditable;

for (var k = 0; k < correctingBits; k++)

{

var sum = 0;

for (var m = 0; m < CodeParameters.HammingCodeLength; m++)

{

if (hammingMatrix[k][m].ToString() == hammingCode[m].ToString() && hammingCode[m].ToString() == "1") sum++;

}

hammingBits += (sum % 2 == 0) ? "0" : "1";

}

var arr = hammingBits.ToCharArray();

Array.Reverse(arr);

results[curIndex].ControlNumber = new string(arr);

var bitToCorrect = 0;

for (var i = 0; i < hammingBits.Length; i++)

{

bitToCorrect += (hammingBits[i] == '0' ? 0 : 1<<i) ;

}

results[curIndex].CorrectedBit = bitToCorrect;

var correctedHammingCode = hammingCode;

if (bitToCorrect != 0)

{

var bit = correctedHammingCode[bitToCorrect - 1];

correctedHammingCode = correctedHammingCode.Remove(bitToCorrect - 1, 1);

correctedHammingCode = correctedHammingCode.Insert(bitToCorrect - 1, bit == '0' ? "1" : "0");

}

results[curIndex].CorrectedHammingCode = correctedHammingCode;

var receivedSymbolCode = "";

for (var i = 0; i < correctedHammingCode.Length; i++)

{

if (!IsPowOfTwo(i + 1))

{

receivedSymbolCode += correctedHammingCode[i];

}

}

results[curIndex].DecodedCode = receivedSymbolCode;

var receivedChar = '-';

var recievedCharCode = 0;

for (var i = 0; i < receivedSymbolCode.Length; i++)

{

if (receivedSymbolCode[i] == '1')

{

recievedCharCode += 1 << (receivedSymbolCode.Length - i - 1);

}

}

foreach (var symbol in selectedAlphabet.Content)

{

if (symbol.Code == recievedCharCode) receivedChar = symbol.Char;

}

results[curIndex].DecodedSymbol = receivedChar;

curIndex++;

}

}

private bool IsPowOfTwo(int a)

{

var cnt = 0;

while (a > 0)

{

if ((a & 1) == 1) cnt++;

a >>= 1;

}

return (cnt == 1);

}

}

  1. Выводы

В результате выполнения лабораторной работы была разработана программа для кодирования и декодирования посредством кодов Хэмминга.

Данный код позволяет исправлять одну ошибку в передаваемых блоках. Также он может обнаружить двойную ошибку, но проблема состоит в том, что двойная ошибка интерпретируется как одинарная, а после ее "исправления" мы почти всегда попадаем на другую разрешенную комбинацию.

Три и более ошибки код Хэмминга фиксировать не способен, т.к. минимальное кодовое расстояние равно 3, т.е. после изменения 3-х или более битов мы почти всегда попадаем на другую разрешенную комбинацию.

Здесь правильнее сказать, что мы можем с определенной вероятностью диагностировать множественную ошибку, если вдруг попадем на запрещенную комбинацию. К сожалению, только диагностировать. Т.е. приемнику снова придется запрашивать пересылку куска данных, где была обнаружена ошибка.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]