1- #nullable enable
1+ // ReSharper disable InconsistentNaming
2+ #nullable enable
23namespace MathCore . Hash . CRC ;
34
4- /// <summary>
5- /// Реализация алгоритма вычисления CRC8 с поддержкой различных полиномов и режимов.
6- /// </summary>
7- public class CRC8 ( byte Polynomial )
5+ /// <summary>Реализация алгоритма вычисления CRC8 с поддержкой различных полиномов и режимов</summary>
6+ /// <remarks>Создаёт экземпляр CRC8 с выбранным полиномом.</remarks>
7+ /// <param name="Polynomial">Полином CRC8</param>
8+ /// <param name="RefIn">Инвертировать входные байты</param>
9+ public class CRC8 ( byte Polynomial , bool RefIn = false )
810{
11+ private const int __TableLength = 256 ;
12+
13+ /// <summary>Таблица CRC8 для текущего полинома.</summary>
14+ private readonly byte [ ] _Table = GetTable ( Polynomial , RefIn ) ;
15+
16+ /// <summary>Текущее состояние CRC.</summary>
17+ public byte State { get ; set ; }
18+
19+ /// <summary>Обновлять ли состояние State после вычисления.</summary>
20+ public bool UpdateState { get ; init ; }
21+
22+ /// <summary>Значение для XOR на выходе.</summary>
23+ public byte XOR { get ; init ; } = 0 ;
24+
25+ /// <summary>Инвертировать входные байты.</summary>
26+ public bool RefIn { get ; init ; } = RefIn ;
27+
28+ /// <summary>Инвертировать результат.</summary>
29+ public bool RefOut { get ; init ; }
30+
931 /// <summary>Создаёт экземпляр CRC8 с выбранным режимом.</summary>
1032 /// <param name="mode">Режим/полином CRC8</param>
11- public CRC8 ( Mode mode = Mode . CRC8 ) : this ( ( byte ) mode ) { }
33+ /// <param name="RefIn">Инвертировать входные байты</param>
34+ public CRC8 ( Mode mode = Mode . CRC8 , bool RefIn = false ) : this ( ( byte ) mode , RefIn ) { }
1235
13- /// <summary>Получить таблицу CRC8 для заданного полинома.</summary>
36+ /// <summary>Получить таблицу CRC8 для заданного полинома и режима отражения входных байтов .</summary>
1437 /// <param name="Polynomial">Полином CRC8</param>
15- /// <returns>Таблица CRC8.</returns>
16- public static byte [ ] GetTable ( byte Polynomial )
38+ /// <param name="RefIn">Отражать входные байты</param>
39+ /// <returns>Таблица CRC8</returns>
40+ public static byte [ ] GetTable ( byte Polynomial , bool RefIn = false )
1741 {
1842 var table = new byte [ __TableLength ] ;
19- FillTable ( table , Polynomial ) ;
43+ FillTable ( table , Polynomial , RefIn ) ;
2044 return table ;
2145 }
2246
23- /// <summary>Заполнить таблицу CRC8 для заданного полинома.</summary>
47+ /// <summary>Заполнить таблицу CRC8 для заданного полинома и режима отражения входных байтов .</summary>
2448 /// <param name="table">Таблица для заполнения</param>
2549 /// <param name="Polynomial">Полином CRC8</param>
26- public static void FillTable ( byte [ ] table , byte Polynomial )
50+ /// <param name="RefIn">Отражать входные байты</param>
51+ public static void FillTable ( byte [ ] table , byte Polynomial , bool RefIn = false )
2752 {
28- if ( table . NotNull ( ) . Length != __TableLength )
29- throw new ArgumentException ( $ "Размер таблицы должен быть { __TableLength } , а составляет { table . Length } ", nameof ( table ) ) ;
53+ if ( table == null || table . Length != __TableLength )
54+ throw new ArgumentException ( $ "Размер таблицы должен быть { __TableLength } , а составляет { table ? . Length } ", nameof ( table ) ) ;
3055
3156 for ( var i = 0 ; i < __TableLength ; i ++ )
3257 {
33- var temp = i ;
58+ var temp = RefIn ? ( ( byte ) i ) . ReverseBits ( ) : i ;
3459 for ( var j = 0 ; j < 8 ; ++ j )
3560 if ( ( temp & 0x80 ) != 0 )
3661 temp = temp << 1 ^ Polynomial ;
3762 else
3863 temp <<= 1 ;
39- table [ i ] = ( byte ) temp ;
64+ table [ i ] = ( byte ) ( RefIn ? ( ( byte ) temp ) . ReverseBits ( ) : temp ) ; // отражаем и индекс, и результат при RefIn
4065 }
4166 }
4267
@@ -73,7 +98,7 @@ public enum Mode : byte
7398 /// <param name="xor">Значение для XOR на выходе</param>
7499 /// <param name="RefIn">Инвертировать входные байты</param>
75100 /// <param name="RefOut">Инвертировать результат</param>
76- /// <returns>Контрольная сумма CRC8. </returns>
101+ /// <returns>Контрольная сумма CRC8</returns>
77102 public static byte Hash (
78103 byte [ ] data ,
79104 Mode mode = Mode . CRC8 ,
@@ -85,103 +110,76 @@ public static byte Hash(
85110 if ( data . NotNull ( ) . Length == 0 )
86111 throw new InvalidOperationException ( ) ;
87112
88- var table = GetTable ( ( byte ) mode ) ;
113+ var table = GetTable ( ( byte ) mode , RefIn ) ;
89114
90- if ( RefIn )
91- foreach ( var b in data )
92- crc = table [ ( crc ^ b . ReverseBits ( ) ) & 0xFF ] ;
93- else
94- foreach ( var b in data )
95- crc = table [ ( crc ^ b ) & 0xFF ] ;
115+ foreach ( var b in data )
116+ crc = table [ ( crc ^ b ) & 0xFF ] ;
96117
97118 crc ^= xor ;
98119
99- return RefOut ? crc . ReverseBits ( ) : crc ;
100- }
101-
102- private const int __TableLength = 256 ;
103-
104- /// <summary>Таблица CRC8 для текущего полинома.</summary>
105- private readonly byte [ ] _Table = GetTable ( Polynomial ) ;
106-
107- /// <summary>Текущее состояние CRC.</summary>
108- public byte State { get ; set ; }
109-
110- /// <summary>Обновлять ли состояние State после вычисления.</summary>
111- public bool UpdateState { get ; set ; }
112-
113- /// <summary>Значение для XOR на выходе.</summary>
114- public byte XOR { get ; set ; } = 0 ;
115-
116- /// <summary>Инвертировать входные байты.</summary>
117- public bool RefIn { get ; set ; }
120+ if ( RefOut )
121+ crc = crc . ReverseBits ( ) ;
118122
119- /// <summary>Инвертировать результат.</summary>
120- public bool RefOut { get ; set ; }
123+ return crc ;
124+ }
121125
122126 /// <summary>Вычислить CRC8 для массива байт</summary>
123127 /// <param name="bytes">Входные данные</param>
124- /// <returns>Контрольная сумма CRC8. </returns>
128+ /// <returns>Контрольная сумма CRC8</returns>
125129 public byte Compute ( params byte [ ] bytes ) => ContinueCompute ( State , bytes ) ;
126130
127131 /// <summary>Продолжить вычисление CRC8 для массива байт с заданным начальным значением</summary>
128132 /// <param name="crc">Начальное значение CRC</param>
129133 /// <param name="bytes">Входные данные</param>
130- /// <returns>Контрольная сумма CRC8. </returns>
134+ /// <returns>Контрольная сумма CRC8</returns>
131135 public byte ContinueCompute ( byte crc , byte [ ] bytes )
132136 {
133- if ( RefIn )
134- foreach ( var b in bytes )
135- crc = _Table [ ( crc ^ b . ReverseBits ( ) ) & 0xFF ] ;
136- else
137- foreach ( var b in bytes )
138- crc = _Table [ ( crc ^ b ) & 0xFF ] ;
137+ foreach ( var b in bytes )
138+ crc = _Table [ ( crc ^ b ) & 0xFF ] ;
139139
140140 crc ^= XOR ;
141141
142142 if ( UpdateState )
143143 State = crc ;
144144
145- return RefOut ? crc . ReverseBits ( ) : crc ;
145+ if ( RefOut )
146+ crc = crc . ReverseBits ( ) ;
147+
148+ return crc ;
146149 }
147150
148151 /// <summary>Вычислить CRC8 для последовательности байт</summary>
149152 /// <param name="bytes">Входные данные</param>
150- /// <returns>Контрольная сумма CRC8. </returns>
153+ /// <returns>Контрольная сумма CRC8</returns>
151154 public byte Compute ( IEnumerable < byte > bytes ) => ContinueCompute ( State , bytes ) ;
152155
153156 /// <summary>Продолжить вычисление CRC8 для последовательности байт с заданным начальным значением</summary>
154157 /// <param name="crc">Начальное значение CRC</param>
155158 /// <param name="bytes">Входные данные</param>
156- /// <returns>Контрольная сумма CRC8. </returns>
159+ /// <returns>Контрольная сумма CRC8</returns>
157160 public byte ContinueCompute ( byte crc , IEnumerable < byte > bytes )
158161 {
159- if ( RefIn )
160- foreach ( var b in bytes )
161- crc = _Table [ ( crc ^ b . ReverseBits ( ) ) & 0xFF ] ;
162- else
163- foreach ( var b in bytes )
164- crc = _Table [ ( crc ^ b ) & 0xFF ] ;
162+ foreach ( var b in bytes )
163+ crc = _Table [ ( crc ^ b ) & 0xFF ] ;
165164
166165 crc ^= XOR ;
167166
168167 if ( UpdateState )
169168 State = crc ;
170169
171- return RefOut ? crc . ReverseBits ( ) : crc ;
170+ if ( RefOut )
171+ crc = crc . ReverseBits ( ) ;
172+
173+ return crc ;
172174 }
173175
174176 /// <summary>Продолжить вычисление CRC8 для массива байт с передачей CRC по ссылке</summary>
175177 /// <param name="crc">CRC по ссылке</param>
176178 /// <param name="bytes">Входные данные</param>
177179 public void Compute ( ref byte crc , byte [ ] bytes )
178180 {
179- if ( RefIn )
180- foreach ( var b in bytes )
181- crc = _Table [ ( crc ^ b . ReverseBits ( ) ) & 0xFF ] ;
182- else
183- foreach ( var b in bytes )
184- crc = _Table [ ( crc ^ b ) & 0xFF ] ;
181+ foreach ( var b in bytes )
182+ crc = _Table [ ( crc ^ b ) & 0xFF ] ;
185183
186184 crc ^= XOR ;
187185
@@ -194,12 +192,8 @@ public void Compute(ref byte crc, byte[] bytes)
194192 /// <param name="bytes">Входные данные</param>
195193 public void Compute ( ref byte crc , IEnumerable < byte > bytes )
196194 {
197- if ( RefIn )
198- foreach ( var b in bytes )
199- crc = _Table [ ( crc ^ b . ReverseBits ( ) ) & 0xFF ] ;
200- else
201- foreach ( var b in bytes )
202- crc = _Table [ ( crc ^ b ) & 0xFF ] ;
195+ foreach ( var b in bytes )
196+ crc = _Table [ ( crc ^ b ) & 0xFF ] ;
203197
204198 crc ^= XOR ;
205199
@@ -209,7 +203,7 @@ public void Compute(ref byte crc, IEnumerable<byte> bytes)
209203
210204 /// <summary>Получить контрольную сумму CRC8 в виде массива байт</summary>
211205 /// <param name="bytes">Входные данные</param>
212- /// <returns>Массив из одного байта с контрольной суммой CRC8. </returns>
206+ /// <returns>Массив из одного байта с контрольной суммой CRC8</returns>
213207 public byte [ ] ComputeChecksumBytes ( params byte [ ] bytes )
214208 {
215209 var crc = Compute ( bytes ) ;
0 commit comments