Click here to Skip to main content
15,892,161 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hello everyone, I need to write a program based on the algorithm of error-correcting coding, the method of cyclic coding. In C# , however, there were difficulties in the course of work, the search did not give results, and my research came to a standstill. Maybe someone has a listing of those programs, I would be grateful. Incorrectly defines the number of the distorted digit


Циклический избыточный код — Википедия[^]

What I have tried:

using System;
 using System.Collections.Generic;
 //using System.Linq;
 using System.Text;
 
 namespace SystemNippel
 {
 publicclassSystemNippel
 {
 //основной модуль программы
 //содержит функции для обработки двоичных комбинаций и
 //кодирования/декодирования по алгоритмам циклического кода
 
 publicstaticstring Polynom = "11111";//порждающиймногочлен
 publicstaticintinf = 11;//количество инф. символов
 publicstaticintcount = 15;//общее колическтов символов
 publicstaticint t = 1;//колическтво исправляемых ошибок
 
 publicstaticintCountMoves=0;//количество левых сдвигов в текущем сеансе декодирования
 //перед началом декодирования должен быть установлен в ноль
 
 publicstaticchar plus(char c1, char c2)
 {
 //сложение разрядов по модудю 2
 if (c1 == '0'&& c2 == '0') return'0';
 if (c1 == '0'&& c2 == '1') return'1';
 if (c1 == '1'&& c2 == '0') return'1';
 if (c1 == '1'&& c2 == '1') return'0';
 
 thrownewException("Ошибка: недопутимый символ");
 return'0';
 
 }
 
 publicstaticstring str_plus(string s1, string s2)
 {
 //сложение двоичных комбинаций по модулю 2
 string s3 = "";
 if (s1.Length != s2.Length) thrownewException("Внутренняяошибка : строкиразнойдлины");
 for (int i = 0; i < s1.Length; i++)
 {
 s3 += plus(s1[i], s2[i]);
 }
 return s3;
 }
 
 publicstaticstring GetRemainder(string x, string d)
 {
 //получение остатка от деления х на d
 string r = "";
 int n; //длина делимого
 int m; //длина делителя
 int z; //указатель текущего положения разряда делимого
 int i; //счетчикцикла
 char[] arr;
 
 z = 0;
 n = x.Length;
 m = d.Length;
 for (i = 0; i < n; i++)//инициализация
 {
 if (x[i] != '0'&& x[i] != '1') thrownewException("Ошибка: недопутимыйсимвол");
 r += x[i];
 }
 arr = r.ToCharArray();
 
 while (true)
 {
 
 for (i = 0; i < m ; i++)
 //прибавляем делитель в текущей позиции указателия
 {
 arr[z + i] =plus(arr[z + i], d[i]);
 }
 while (arr[z] == '0') {
 z++;//сдвиг указателя влево, до первой единицы
 if (z >= arr.Length) break;
 }
 if (z > n - m) break;//конец деления
 
 }
 r = newstring(arr);
 
 return r;
 }
 
 publicstaticstring Coder(string s)
 {
 //кодирование двоичной комбинации
 stringstr = "";
 string output = "";
 int r;
 
 str = s;
 r=count-inf;
 for(int i=0;i<r;i++){
 //увеличиваем длину строки до общего количества символов
 str += '0';
 }
 output = str;
 str = GetRemainder(str, Polynom);//остаток от деления на порождающий многочлен
 output = str_plus(output, str);//сложениесостатком
 return output;
 
 }
 
 publicstaticstring Transfer(string s, int bit)
 {
 //передача символа
 //моделирует искажение выбранного бита (номер бита начинается с нуля)
 char[] arr = s.ToCharArray();
 if (arr[bit] == '0') { arr[bit] = '1'; }
 elseif (arr[bit] == '1') { arr[bit] = '0'; }
 returnnewstring(arr);
 
 }
 
 publicstaticint GetWeight(string s)
 {
 //вычисляет количество единиц в двоичной комбинации
 int i;
 int c=0;
 for (i = 0; i < s.Length; i++)
 {
 if (s[i] == '1') c++;
 }
 return c;
 }
 publicstaticstring MoveLeft(string s)
 {
 //левый цикл.сдвиг двоичной комбинации на один разряд
 stringres;
 res = s.Substring(1, s.Length - 1);
 res += s[0];
 returnres;
 }
 
 publicstaticstring MoveRight(string s)
 {
 //правый цикл.сдвиг двоичной комбинации на один разряд
 stringres="";
 res += s[s.Length - 1];
 res += s.Substring(0, s.Length - 1);
 return res;
 }
 
 publicstaticbool CheckString(string str)
 {
 //проверка корректности введенной двоичной строки
 //для правильной строки возвращает ИСТИНА
 int i;
 if (str.Length == 0) returnfalse;
 for ( i = 0; i < str.Length; i++)
 {
 if (str[i] != '0'&& str[i] != '1') returnfalse;
 }
 returntrue;
 
 }
 
 //генерация случайной двоичной комбинации
 //длина комбинации соответствует длине инф. части
 publicstaticstring NewRandomNippel()
 {
 Random rnd = newRandom();
 String str = "";
 int i;
 for (i = 0; i < inf; i++)
 {
 str += rnd.Next(2).ToString();
 }
 return str;
 
 }
 }
 }
Posted
Updated 21-Jan-19 11:20am
Comments
Richard MacCutchan 21-Jan-19 5:02am    
What is the problem?
Andrey_Smolensky 21-Jan-19 5:46am    
Incorrectly defines the number of the distorted digit

1 solution

Here's mine; 16 bit; trailing CRC code.

All this depends on the architecture (big vs little Endian).

/// <summary>
      /// Checks for a valid CRC.
      /// </summary>
      public static bool HasValidCRC( byte[] buffer, int count ) {

         // Bytes read must be at least 3 in order to have a valid 2 byte CRC.
         if ( count <= 3 ) {
            // Invalid; not enough info.
            return false;
         }

         // CRC receipt = low-order byte; then high-order byte.
         byte[] bufferCRC =
            new byte[] { buffer[ count - 2 ], buffer[ count - 1 ] };

         byte[] calculatedCRC =
            FunctionBase.CalculateModbusCRC16( buffer, count - 2 );

         if ( bufferCRC[ 0 ] != calculatedCRC[ 0 ] ||
              bufferCRC[ 1 ] != calculatedCRC[ 1 ] ) {

            // Not a valid CRC.
            return false;
         }

         // Valid CRC.
         return true;
      }

      /// <summary>
      /// Calculate CRC as a byte array.
      /// </summary>
      private static byte[] CalculateModbusCRC16( byte[] packet, int length ) {

         // Intialize CRC.
         ushort crc = 0xFFFF;

         // Loop thru packet.
         for ( int i = 0; i < length; i++ ) {

            // XOR a packet byte with the CRC.
            crc ^= ( ushort ) packet[ i ];

            // Loop thru all 8 data bits.
            for ( int j = 0; j < 8; j++ ) {

               // If the LSB is 1, shift the CRC and XOR
               // the polynomial mask (0xA001) with the CRC;
               // else, shift the CRC only.

               if ( ( crc & 0x0001 ) == 1 ) {
                  crc >>= 1;
                  crc ^= 0xA001;
               } else {
                  crc >>= 1;
               }

            }  // end for j;

         }  // end for i;

         byte[] crcBytes = BitConverter.GetBytes( crc );

         // Modbus CRC is transmitted with the low-order byte first.
         if ( BitConverter.IsLittleEndian == false ) {
            crcBytes = ReverseBytes( crcBytes );
         }

         return crcBytes;
      }

      /// <summary>
      /// Reverse bytes for network transmission. 
      /// </summary>
      private static byte[] ReverseBytes( byte[] inArray ) {

         int i = inArray.Length;
         byte[] outArray = new byte[ i ];

         foreach ( byte b in inArray ) {
            i--;
            outArray[ i ] = b;
         }

         return outArray;
      }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900