Andrey_Smolensky Ответов: 1

Циклическая проверка избыточности, CRC


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


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

Что я уже пробовал:

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;
 
 }
 }
 }

Richard MacCutchan

В чем же проблема?

Andrey_Smolensky

Неверно определяет номер искаженной цифры

1 Ответов

Рейтинг:
1

Gerry Schmitz

Вот мой; 16 бит; завершающий CRC-код.

Все это зависит от архитектуры (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;
      }