用於學習記錄
原文載自:https://www.cnblogs.com/ayxj/p/11481969.html
用C#實現的幾種常用數據校驗方法整理(CRC校驗;LRC校驗;BCC校驗;累加和校驗)
CRC即循環冗余校驗碼(Cyclic Redundancy Check):是數據通信領域中最常用的一種查錯校驗碼,其特征是信息字段和校驗字段的長度可以任意選定。循環冗余檢查(CRC)是一種數據傳輸檢錯功能,對數據進行多項式計算,並將得到的結果附在幀的后面,接收設備也執行類似的算法,以保證數據傳輸的正確性和完整性。
/// CRC算法參數模型解釋:
/// NAME:參數模型名稱。
///WIDTH:寬度,即CRC比特數。
/// POLY:生成項的簡寫,以16進制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成項是0x104C11DB7。
///INIT:這是算法開始時寄存器(crc)的初始化預置值,十六進制表示。
///REFIN:待測數據的每個字節是否按位反轉,True或False。
/// REFOUT:在計算后之后,異或輸出之前,整個數據是否按位反轉,True或False。
/// XOROUT:計算結果與此參數異或后得到最終的CRC值。
1 /// ********************************************************************** 2 /// Name: CRC-4/ITU x4+x+1 3 /// Poly: 0x03 4 /// Init: 0x00 5 /// Refin: true 6 /// Refout: true 7 /// Xorout: 0x00 8 ///************************************************************************* 9 public static byte[] Crc1(byte[] buffer, int start = 0, int len = 0) 10 { 11 if (buffer == null || buffer.Length == 0) return null; 12 if (start < 0) return null; 13 if (len == 0) len = buffer.Length - start; 14 int length = start + len; 15 if (length > buffer.Length) return null; 16 byte crc = 0;// Initial value 17 for (int i = start; i < length; i++) 18 { 19 crc ^= buffer[i]; 20 for (int j = 0; j < 8; j++) 21 { 22 if ((crc & 1) > 0) 23 crc = (byte)((crc >> 1) ^ 0x0C);//0x0C = (reverse 0x03)>>(8-4) 24 else 25 crc = (byte)(crc >> 1); 26 } 27 } 28 return new byte[] { crc }; 29 } 30 /// ********************************************************************** 31 /// Name: CRC-5/EPC x5+x3+1 32 /// Poly: 0x09 33 /// Init: 0x09 34 /// Refin: false 35 /// Refout: false 36 /// Xorout: 0x00 37 ///************************************************************************* 38 public static byte[] Crc2(byte[] buffer, int start = 0, int len = 0) 39 { 40 if (buffer == null || buffer.Length == 0) return null; 41 if (start < 0) return null; 42 if (len == 0) len = buffer.Length - start; 43 int length = start + len; 44 if (length > buffer.Length) return null; 45 byte crc = 0x48;// Initial value: 0x48 = 0x09<<(8-5) 46 for (int i = start; i < length; i++) 47 { 48 crc ^= buffer[i]; 49 for (int j = 0; j < 8; j++) 50 { 51 if ((crc & 0x80) > 0) 52 crc = (byte)((crc << 1) ^ 0x48);// 0x48 = 0x09<<(8-5) 53 else 54 crc = (byte)(crc << 1); 55 } 56 } 57 return new byte[] { (byte)(crc >> 3) }; 58 } 59 /// ********************************************************************** 60 /// Name: CRC-5/ITU x5+x4+x2+1 61 /// Poly: 0x15 62 /// Init: 0x00 63 /// Refin: true 64 /// Refout: true 65 /// Xorout: 0x00 66 ///************************************************************************* 67 public static byte[] Crc3(byte[] buffer, int start = 0, int len = 0) 68 { 69 if (buffer == null || buffer.Length == 0) return null; 70 if (start < 0) return null; 71 if (len == 0) len = buffer.Length - start; 72 int length = start + len; 73 if (length > buffer.Length) return null; 74 byte crc = 0;// Initial value 75 for (int i = start; i < length; i++) 76 { 77 crc ^= buffer[i]; 78 for (int j = 0; j < 8; j++) 79 { 80 if ((crc & 1) > 0) 81 crc = (byte)((crc >> 1) ^ 0x15);// 0x15 = (reverse 0x15)>>(8-5) 82 else 83 crc = (byte)(crc >> 1); 84 } 85 } 86 return new byte[] { crc }; 87 } 88 /// ********************************************************************** 89 /// Name: CRC-5/USB x5+x2+1 90 /// Poly: 0x05 91 /// Init: 0x1F 92 /// Refin: true 93 /// Refout: true 94 /// Xorout: 0x1F 95 ///************************************************************************* 96 public static byte[] Crc4(byte[] buffer, int start = 0, int len = 0) 97 { 98 if (buffer == null || buffer.Length == 0) return null; 99 if (start < 0) return null; 100 if (len == 0) len = buffer.Length - start; 101 int length = start + len; 102 if (length > buffer.Length) return null; 103 byte crc = 0x1F;// Initial value 104 for (int i = start; i < length; i++) 105 { 106 crc ^= buffer[i]; 107 for (int j = 0; j < 8; j++) 108 { 109 if ((crc & 1) > 0) 110 crc = (byte)((crc >> 1) ^ 0x14);// 0x14 = (reverse 0x05)>>(8-5) 111 else 112 crc = (byte)(crc >> 1); 113 } 114 } 115 return new byte[] {(byte)( crc ^ 0x1F) }; 116 } 117 /// ********************************************************************** 118 /// Name: CRC-6/ITU x6+x+1 119 /// Poly: 0x03 120 /// Init: 0x00 121 /// Refin: true 122 /// Refout: true 123 /// Xorout: 0x00 124 ///************************************************************************* 125 public static byte[] Crc5(byte[] buffer, int start = 0, int len = 0) 126 { 127 if (buffer == null || buffer.Length == 0) return null; 128 if (start < 0) return null; 129 if (len == 0) len = buffer.Length - start; 130 int length = start + len; 131 if (length > buffer.Length) return null; 132 byte crc = 0;// Initial value 133 for (int i = start; i < length; i++) 134 { 135 crc ^= buffer[i]; 136 for (int j = 0; j < 8; j++) 137 { 138 if ((crc & 1) > 0) 139 crc = (byte)((crc >> 1) ^ 0x30);// 0x30 = (reverse 0x03)>>(8-6) 140 else 141 crc = (byte)(crc >> 1); 142 } 143 } 144 return new byte[] { crc }; 145 } 146 /// ********************************************************************** 147 /// Name: CRC-7/MMC x7+x3+1 148 /// Poly: 0x09 149 /// Init: 0x00 150 /// Refin: false 151 /// Refout: false 152 /// Xorout: 0x00 153 ///************************************************************************* 154 public static byte[] Crc6(byte[] buffer, int start = 0, int len = 0) 155 { 156 if (buffer == null || buffer.Length == 0) return null; 157 if (start < 0) return null; 158 if (len == 0) len = buffer.Length - start; 159 int length = start + len; 160 if (length > buffer.Length) return null; 161 byte crc = 0;// Initial value 162 for (int i = start; i < length; i++) 163 { 164 crc ^= buffer[i]; 165 for (int j = 0; j < 8; j++) 166 { 167 if ((crc & 0x80) > 0) 168 crc = (byte)((crc << 1) ^ 0x12);// 0x12 = 0x09<<(8-7) 169 else 170 crc = (byte)(crc << 1); 171 } 172 } 173 return new byte[] { (byte)(crc >> 1) }; 174 } 175 /// ********************************************************************** 176 /// Name: CRC8 x8+x2+x+1 177 /// Poly: 0x07 178 /// Init: 0x00 179 /// Refin: false 180 /// Refout: false 181 /// Xorout: 0x00 182 ///************************************************************************* 183 public static byte[] Crc7(byte[] buffer, int start = 0, int len = 0) 184 { 185 if (buffer == null || buffer.Length == 0) return null; 186 if (start < 0) return null; 187 if (len == 0) len = buffer.Length - start; 188 int length = start + len; 189 if (length > buffer.Length) return null; 190 byte crc = 0;// Initial value 191 for (int i = start; i < length; i++) 192 { 193 crc ^= buffer[i]; 194 for (int j = 0; j < 8; j++) 195 { 196 if ((crc & 0x80) > 0) 197 crc = (byte)((crc << 1) ^ 0x07); 198 else 199 crc = (byte)(crc << 1); 200 } 201 } 202 return new byte[] { crc }; 203 } 204 /// ********************************************************************** 205 /// Name: CRC-8/ITU x8+x2+x+1 206 /// Poly: 0x07 207 /// Init: 0x00 208 /// Refin: false 209 /// Refout: false 210 /// Xorout: 0x55 211 ///************************************************************************* 212 public static byte[] Crc8(byte[] buffer, int start = 0, int len = 0) 213 { 214 if (buffer == null || buffer.Length == 0) return null; 215 if (start < 0) return null; 216 if (len == 0) len = buffer.Length - start; 217 int length = start + len; 218 if (length > buffer.Length) return null; 219 byte crc = 0;// Initial value 220 for (int i = start; i < length; i++) 221 { 222 crc ^= buffer[i]; 223 for (int j = 0; j < 8; j++) 224 { 225 if ((crc & 0x80) > 0) 226 crc = (byte)((crc << 1) ^ 0x07); 227 else 228 crc = (byte)(crc << 1); 229 } 230 } 231 return new byte[] { (byte)(crc ^ 0x55) }; 232 } 233 /// ********************************************************************** 234 /// Name: CRC-8/MAXIM x8+x5+x4+1 235 /// Poly: 0x31 236 /// Init: 0x00 237 /// Refin: true 238 /// Refout: true 239 /// Xorout: 0x00 240 ///************************************************************************* 241 public static byte[] Crc9(byte[] buffer, int start = 0, int len = 0) 242 { 243 if (buffer == null || buffer.Length == 0) return null; 244 if (start < 0) return null; 245 if (len == 0) len = buffer.Length - start; 246 int length = start + len; 247 if (length > buffer.Length) return null; 248 byte crc = 0;// Initial value 249 for (int i = start; i < length; i++) 250 { 251 crc ^= buffer[i]; 252 for (int j = 0; j < 8; j++) 253 { 254 if ((crc & 1) > 0) 255 crc = (byte)((crc >> 1) ^ 0x8C);// 0x8C = reverse 0x31 256 else 257 crc = (byte)(crc >> 1); 258 } 259 } 260 return new byte[] { crc }; 261 } 262 /// ********************************************************************** 263 /// Name: CRC-8/ROHC x8+x2+x+1 264 /// Poly: 0x07 265 /// Init: 0xFF 266 /// Refin: true 267 /// Refout: true 268 /// Xorout: 0x00 269 ///************************************************************************* 270 public static byte[] Crc10(byte[] buffer, int start = 0, int len = 0) 271 { 272 if (buffer == null || buffer.Length == 0) return null; 273 if (start < 0) return null; 274 if (len == 0) len = buffer.Length - start; 275 int length = start + len; 276 if (length > buffer.Length) return null; 277 byte crc = 0xFF;// Initial value 278 for (int i = start; i < length; i++) 279 { 280 crc ^= buffer[i]; 281 for (int j = 0; j < 8; j++) 282 { 283 if ((crc & 1) > 0) 284 crc = (byte)((crc >> 1) ^ 0xE0);// 0xE0 = reverse 0x07 285 else 286 crc = (byte)(crc >> 1); 287 } 288 } 289 return new byte[] { crc }; 290 } 291 /// Z1協議校驗碼計算 292 static byte[] table = { 0x00, 0x1C, 0x38, 0x24, 0x70, 0x6C, 0x48, 0x54, 0xE0, 0xFC, 293 0xD8, 0xC4, 0x90, 0x8C, 0xA8, 0xB4, 0xDC, 0xC0, 0xE4, 0xF8, 294 0xAC, 0xB0, 0x94, 0x88, 0x3C, 0x20, 0x04, 0x18, 0x4C, 0x50, 295 0x74, 0x68, 0xA4, 0xB8, 0x9C, 0x80, 0xD4, 0xC8, 0xEC, 0xF0, 296 0x44, 0x58, 0x7C, 0x60, 0x34, 0x28, 0x0C, 0x10, 0x78, 0x64, 297 0x40, 0x5C, 0x08, 0x14, 0x30, 0x2C, 0x98, 0x84, 0xA0, 0xBC, 298 0xE8, 0xF4, 0xD0, 0xCC, 0x54, 0x48, 0x6C, 0x70, 0x24, 0x38, 299 0x1C, 0x00, 0xB4, 0xA8, 0x8C, 0x90, 0xC4, 0xD8, 0xFC, 0xE0, 300 0x88, 0x94, 0xB0, 0xAC, 0xF8, 0xE4, 0xC0, 0xDC, 0x68, 0x74, 301 0x50, 0x4C, 0x18, 0x04, 0x20, 0x3C, 0xF0, 0xEC, 0xC8, 0xD4, 302 0x80, 0x9C, 0xB8, 0xA4, 0x10, 0x0C, 0x28, 0x34, 0x60, 0x7C, 303 0x58, 0x44, 0x2C, 0x30, 0x14, 0x08, 0x5C, 0x40, 0x64, 0x78, 304 0xCC, 0xD0, 0xF4, 0xE8, 0xBC, 0xA0, 0x84, 0x98, 0xA8, 0xB4, 305 0x90, 0x8C, 0xD8, 0xC4, 0xE0, 0xFC, 0x48, 0x54, 0x70, 0x6C, 306 0x38, 0x24, 0x00, 0x1C, 0x74, 0x68, 0x4C, 0x50, 0x04, 0x18, 307 0x3C, 0x20, 0x94, 0x88, 0xAC, 0xB0, 0xE4, 0xF8, 0xDC, 0xC0, 308 0x0C, 0x10, 0x34, 0x28, 0x7C, 0x60, 0x44, 0x58, 0xEC, 0xF0, 309 0xD4, 0xC8, 0x9C, 0x80, 0xA4, 0xB8, 0xD0, 0xCC, 0xE8, 0xF4, 310 0xA0, 0xBC, 0x98, 0x84, 0x30, 0x2C, 0x08, 0x14, 0x40, 0x5C, 311 0x78, 0x64, 0xFC, 0xE0, 0xC4, 0xD8, 0x8C, 0x90, 0xB4, 0xA8, 312 0x1C, 0x00, 0x24, 0x38, 0x6C, 0x70, 0x54, 0x48, 0x20, 0x3C, 313 0x18, 0x04, 0x50, 0x4C, 0x68, 0x74, 0xC0, 0xDC, 0xF8, 0xE4, 314 0xB0, 0xAC, 0x88, 0x94, 0x58, 0x44, 0x60, 0x7C, 0x28, 0x34, 315 0x10, 0x0C, 0xB8, 0xA4, 0x80, 0x9C, 0xC8, 0xD4, 0xF0, 0xEC, 316 0x84, 0x98, 0xBC, 0xA0, 0xF4, 0xE8, 0xCC, 0xD0, 0x64, 0x78, 317 0x5C, 0x40, 0x14, 0x08, 0x2C, 0x30 318 }; 319 public static byte[] Crc11(byte[] buffer, int start = 0, int len = 0) 320 { 321 if (buffer == null || buffer.Length == 0) return null; 322 if (start < 0) return null; 323 if (len == 0) len = buffer.Length - start; 324 int length = start + len; 325 if (length > buffer.Length) return null; 326 int i; 327 byte crc = 0x00; 328 int tableIndex; 329 for (i = start; i < length; i++) 330 { 331 tableIndex = crc ^ (buffer[i] & 0xFF); 332 crc = table[tableIndex]; 333 } 334 return new byte[] { crc }; 335 } 336 /// ********************************************************************** 337 /// Name: CRC-12 x16+x12+x5+1 338 /// Poly: 0x80 339 /// Init: 0x0000 340 /// Refin: true 341 /// Refout: true 342 /// Xorout: 0x0000 343 ///************************************************************************* 344 public static byte[] Crc12(byte[] buffer, int start = 0, int len = 0) 345 { 346 if (buffer == null || buffer.Length == 0) return null; 347 if (start < 0) return null; 348 if (len == 0) len = buffer.Length - start; 349 int length = start + len; 350 if (length > buffer.Length) return null; 351 ushort crc = 0;// Initial value 352 short iQ = 0, iR = 0; 353 for (int i = start; i < length; i++) 354 { 355 // 多項式除法 356 // 如果該位為1 357 if ((buffer[i] & (0x80 >> iR)) > 0) 358 { 359 // 則在余數尾部添1否則添0 360 crc |= 0x01; 361 } 362 // 如果12位除數中的最高位為1,則夠除 363 if (crc >= 0x1000) 364 { 365 crc ^= 0x180D; 366 } 367 crc <<= 1; 368 iR++; 369 if (8 == iR) 370 { 371 iR = 0; 372 iQ++; 373 } 374 } 375 // 對后面添加的12個0做處理 376 for (int i = 0; i < 12; i++) 377 { 378 if (crc >= 0x1000) 379 { 380 crc ^= 0x180D; 381 } 382 crc <<= 1; 383 } 384 crc >>= 1; 385 byte[] ret = BitConverter.GetBytes(crc); 386 Array.Reverse(ret); 387 return ret; 388 } 389 /// ********************************************************************** 390 /// Name: CRC-16/CCITT x16+x12+x5+1 391 /// Poly: 0x1021 392 /// Init: 0x0000 393 /// Refin: true 394 /// Refout: true 395 /// Xorout: 0x0000 396 ///************************************************************************* 397 public static byte[] Crc13(byte[] buffer, int start = 0, int len = 0) 398 { 399 if (buffer == null || buffer.Length == 0) return null; 400 if (start < 0) return null; 401 if (len == 0) len = buffer.Length - start; 402 int length = start + len; 403 if (length > buffer.Length) return null; 404 ushort crc = 0;// Initial value 405 for (int i = start; i < length; i++) 406 { 407 crc ^= buffer[i]; 408 for (int j = 0; j < 8; j++) 409 { 410 if ((crc & 1) > 0) 411 crc = (ushort)((crc >> 1) ^ 0x8408);// 0x8408 = reverse 0x1021 412 else 413 crc = (ushort)(crc >> 1); 414 } 415 } 416 byte[] ret = BitConverter.GetBytes(crc); 417 Array.Reverse(ret); 418 return ret; 419 } 420 /// ********************************************************************** 421 /// Name: CRC-16/CCITT FALSE x16+x12+x5+1 422 /// Poly: 0x1021 423 /// Init: 0xFFFF 424 /// Refin: false 425 /// Refout: false 426 /// Xorout: 0x0000 427 ///************************************************************************* 428 public static byte[] Crc14(byte[] buffer, int start = 0, int len = 0) 429 { 430 if (buffer == null || buffer.Length == 0) return null; 431 if (start < 0) return null; 432 if (len == 0) len = buffer.Length - start; 433 int length = start + len; 434 if (length > buffer.Length) return null; 435 ushort crc = 0xFFFF;// Initial value 436 for (int i = start; i < length; i++) 437 { 438 crc ^= (ushort)(buffer[i] << 8); 439 for (int j = 0; j < 8; j++) 440 { 441 if ((crc & 0x8000) > 0) 442 crc = (ushort)((crc << 1) ^ 0x1021); 443 else 444 crc = (ushort)(crc << 1); 445 } 446 } 447 byte[] ret = BitConverter.GetBytes(crc); 448 Array.Reverse(ret); 449 return ret; 450 } 451 /// ********************************************************************** 452 /// Name: CRC-16/DNP x16+x13+x12+x11+x10+x8+x6+x5+x2+1 453 /// Poly: 0x3D65 454 /// Init: 0x0000 455 /// Refin: true 456 /// Refout: true 457 /// Xorout: 0xFFFF 458 ///************************************************************************* 459 public static byte[] Crc15(byte[] buffer, int start = 0, int len = 0) 460 { 461 if (buffer == null || buffer.Length == 0) return null; 462 if (start < 0) return null; 463 if (len == 0) len = buffer.Length - start; 464 int length = start + len; 465 if (length > buffer.Length) return null; 466 ushort crc = 0;// Initial value 467 for (int i = start; i < length; i++) 468 { 469 crc ^= buffer[i]; 470 for (int j = 0; j < 8; j++) 471 { 472 if ((crc & 1) > 0) 473 crc = (ushort)((crc >> 1) ^ 0xA6BC);// 0xA6BC = reverse 0x3D65 474 else 475 crc = (ushort)(crc >> 1); 476 } 477 } 478 byte[] ret = BitConverter.GetBytes((ushort)~crc); 479 Array.Reverse(ret); 480 return ret; 481 } 482 /// ********************************************************************** 483 /// Name: CRC-16/IBM x16+x15+x2+1 484 /// Poly: 0x8005 485 /// Init: 0x0000 486 /// Refin: true 487 /// Refout: true 488 /// Xorout: 0x0000 489 ///************************************************************************* 490 public static byte[] Crc16(byte[] buffer, int start = 0, int len = 0) 491 { 492 if (buffer == null || buffer.Length == 0) return null; 493 if (start < 0) return null; 494 if (len == 0) len = buffer.Length - start; 495 int length = start + len; 496 if (length > buffer.Length) return null; 497 ushort crc = 0;// Initial value 498 for (int i = start; i < length; i++) 499 { 500 crc ^= buffer[i]; 501 for (int j = 0; j < 8; j++) 502 { 503 if ((crc & 1) > 0) 504 crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 505 else 506 crc = (ushort)(crc >> 1); 507 } 508 } 509 byte[] ret = BitConverter.GetBytes(crc); 510 Array.Reverse(ret); 511 return ret; 512 } 513 /// ********************************************************************** 514 /// Name: CRC-16/MAXIM x16+x15+x2+1 515 /// Poly: 0x8005 516 /// Init: 0x0000 517 /// Refin: true 518 /// Refout: true 519 /// Xorout: 0xFFFF 520 ///************************************************************************* 521 public static byte[] Crc17(byte[] buffer, int start = 0, int len = 0) 522 { 523 if (buffer == null || buffer.Length == 0) return null; 524 if (start < 0) return null; 525 if (len == 0) len = buffer.Length - start; 526 int length = start + len; 527 if (length > buffer.Length) return null; 528 ushort crc = 0;// Initial value 529 for (int i = start; i < length; i++) 530 { 531 crc ^= buffer[i]; 532 for (int j = 0; j < 8; j++) 533 { 534 if ((crc & 1) > 0) 535 crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 536 else 537 crc = (ushort)(crc >> 1); 538 } 539 } 540 byte[] ret = BitConverter.GetBytes((ushort)~crc); 541 Array.Reverse(ret); 542 return ret; 543 } 544 /// ********************************************************************** 545 /// Name: CRC-16/MODBUS x16+x15+x2+1 546 /// Poly: 0x8005 547 /// Init: 0xFFFF 548 /// Refin: true 549 /// Refout: true 550 /// Xorout: 0x0000 551 ///************************************************************************* 552 public static byte[] Crc18(byte[] buffer, int start = 0, int len = 0) 553 { 554 if (buffer == null || buffer.Length == 0) return null; 555 if (start < 0) return null; 556 if (len == 0) len = buffer.Length - start; 557 int length = start + len; 558 if (length > buffer.Length) return null; 559 ushort crc = 0xFFFF;// Initial value 560 for (int i = start; i < length; i++) 561 { 562 crc ^= buffer[i]; 563 for (int j = 0; j < 8; j++) 564 { 565 if ((crc & 1) > 0) 566 crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 567 else 568 crc = (ushort)(crc >> 1); 569 } 570 } 571 byte[] ret = BitConverter.GetBytes(crc); 572 Array.Reverse(ret); 573 return ret; 574 } 575 /// ********************************************************************** 576 /// Name: CRC-16/USB x16+x15+x2+1 577 /// Poly: 0x8005 578 /// Init: 0xFFFF 579 /// Refin: true 580 /// Refout: true 581 /// Xorout: 0xFFFF 582 ///************************************************************************* 583 public static byte[] Crc19(byte[] buffer, int start = 0, int len = 0) 584 { 585 if (buffer == null || buffer.Length == 0) return null; 586 if (start < 0) return null; 587 if (len == 0) len = buffer.Length - start; 588 int length = start + len; 589 if (length > buffer.Length) return null; 590 ushort crc = 0xFFFF;// Initial value 591 for (int i = start; i < length; i++) 592 { 593 crc ^= buffer[i]; 594 for (int j = 0; j < 8; j++) 595 { 596 if ((crc & 1) > 0) 597 crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005 598 else 599 crc = (ushort)(crc >> 1); 600 } 601 } 602 byte[] ret = BitConverter.GetBytes((ushort)~crc); 603 Array.Reverse(ret); 604 return ret; 605 } 606 /// ********************************************************************** 607 /// Name: CRC-16/X25 x16+x12+x5+1 608 /// Poly: 0x1021 609 /// Init: 0xFFFF 610 /// Refin: true 611 /// Refout: true 612 /// Xorout: 0xFFFF 613 ///************************************************************************* 614 public static byte[] Crc20(byte[] buffer, int start = 0, int len = 0) 615 { 616 if (buffer == null || buffer.Length == 0) return null; 617 if (start < 0) return null; 618 if (len == 0) len = buffer.Length - start; 619 int length = start + len; 620 if (length > buffer.Length) return null; 621 ushort crc = 0xFFFF;// Initial value 622 for (int i = start; i < length; i++) 623 { 624 crc ^= buffer[i]; 625 for (int j = 0; j < 8; j++) 626 { 627 if ((crc & 1) > 0) 628 crc = (ushort)((crc >> 1) ^ 0x8408);// 0x8408 = reverse 0x1021 629 else 630 crc = (ushort)(crc >> 1); 631 } 632 } 633 byte[] ret = BitConverter.GetBytes((ushort)~crc); 634 Array.Reverse(ret); 635 return ret; 636 } 637 /// ********************************************************************** 638 /// Name: CRC-16/XMODEM x16+x12+x5+1 639 /// Poly: 0x1021 640 /// Init: 0x0000 641 /// Refin: false 642 /// Refout: false 643 /// Xorout: 0x0000 644 ///************************************************************************* 645 public static byte[] Crc21(byte[] buffer, int start = 0, int len = 0) 646 { 647 if (buffer == null || buffer.Length == 0) return null; 648 if (start < 0) return null; 649 if (len == 0) len = buffer.Length - start; 650 int length = start + len; 651 if (length > buffer.Length) return null; 652 ushort crc = 0;// Initial value 653 for (int i = start; i < length; i++) 654 { 655 crc ^= (ushort)(buffer[i] << 8); 656 for (int j = 0; j < 8; j++) 657 { 658 if ((crc & 0x8000) > 0) 659 crc = (ushort)((crc << 1) ^ 0x1021); 660 else 661 crc = (ushort)(crc << 1); 662 } 663 } 664 byte[] ret = BitConverter.GetBytes(crc); 665 Array.Reverse(ret); 666 return ret; 667 } 668 /// ********************************************************************** 669 /// Name: CRC32 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 670 /// Poly: 0x04C11DB7 671 /// Init: 0xFFFFFFFF 672 /// Refin: true 673 /// Refout: true 674 /// Xorout: 0xFFFFFFFF 675 ///************************************************************************* 676 public static byte[] Crc22(byte[] buffer, int start = 0, int len = 0) 677 { 678 if (buffer == null || buffer.Length == 0) return null; 679 if (start < 0) return null; 680 if (len == 0) len = buffer.Length - start; 681 int length = start + len; 682 if (length > buffer.Length) return null; 683 uint crc = 0xFFFFFFFF;// Initial value 684 for (int i = start; i < length; i++) 685 { 686 crc ^= buffer[i]; 687 for (int j = 0; j < 8; j++) 688 { 689 if ((crc & 1) > 0) 690 crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7 691 else 692 crc = crc >> 1; 693 } 694 } 695 byte[] ret = BitConverter.GetBytes(~crc); 696 Array.Reverse(ret); 697 return ret; 698 } 699 /// ********************************************************************** 700 /// Name: CRC32/MPEG-2 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 701 /// Poly: 0x04C11DB7 702 /// Init: 0xFFFFFFFF 703 /// Refin: false 704 /// Refout: false 705 /// Xorout: 0x00000000 706 ///************************************************************************* 707 public static byte[] Crc23(byte[] buffer, int start = 0, int len = 0) 708 { 709 if (buffer == null || buffer.Length == 0) return null; 710 if (start < 0) return null; 711 if (len == 0) len = buffer.Length - start; 712 int length = start + len; 713 if (length > buffer.Length) return null; 714 uint crc = 0xFFFFFFFF;// Initial value 715 for (int i = start; i < length; i++) 716 { 717 crc ^= (uint)(buffer[i] << 24); 718 for (int j = 0; j < 8; j++) 719 { 720 if ((crc & 0x80000000) > 0) 721 crc = (crc << 1) ^ 0x04C11DB7; 722 else 723 crc = crc << 1; 724 } 725 } 726 byte[] ret = BitConverter.GetBytes(crc); 727 Array.Reverse(ret); 728 return ret; 729 }
縱向冗余校驗(Longitudinal Redundancy Check,簡稱:LRC)是通信中常用的一種校驗形式,也稱LRC校驗或縱向校驗。 它是一種從縱向通道上的特定比特串產生校驗比特的錯誤檢測方法。在行列格式中(如磁帶),LRC經常是與VRC一起使用,這樣就會為每個字符校驗碼。在工業領域Modbus協議Ascii模式采用該算法。 LRC計算校驗碼,具體算法如下:
/// 1、對需要校驗的數據(2n個字符)兩兩組成一個16進制的數值求和。
/// 2、將求和結果與256求模。
/// 3、用256減去所得模值得到校驗結果(另一種方法:將模值按位取反然后加1)。
1 public static byte[] Lrc(byte[] buffer, int start = 0, int len = 0) 2 { 3 if (buffer == null || buffer.Length == 0) return null; 4 if (start < 0) return null; 5 if (len == 0) len = buffer.Length - start; 6 int length = start + len; 7 if (length > buffer.Length) return null; 8 byte lrc = 0;// Initial value 9 for (int i = start; i < len; i++) 10 { 11 lrc += buffer[i]; 12 } 13 lrc = (byte)((lrc ^ 0xFF) + 1); 14 return new byte[] { lrc }; 15 }
BCC(Block Check Character/信息組校驗碼),因校驗碼是將所有數據異或得出,故俗稱異或校驗。具體算法是:將每一個字節的數據(一般是兩個16進制的字符)進行異或后即得到校驗碼。
public static byte[] Bcc(byte[] buffer, int start = 0, int len = 0) { if (buffer == null || buffer.Length == 0) return null; if (start < 0) return null; if (len == 0) len = buffer.Length - start; int length = start + len; if (length > buffer.Length) return null; byte bcc = 0;// Initial value for (int i = start; i < len; i++) { bcc ^= buffer[i]; } return new byte[] { bcc }; }
檢驗和(checksum),在數據處理和數據通信領域中,用於校驗目的地一組數據項的和。它通常是以十六進制為數制表示的形式。如果校驗和的數值超過十六進制的FF,也就是255. 就要求其補碼作為校驗和。通常用來在通信中,尤其是遠距離通信中保證數據的完整性和准確性。
1 public static byte[] allAdd(byte[] buffer, int start = 0, int len = 0) 2 { 3 if (buffer == null || buffer.Length == 0) return null; 4 if (start < 0) return null; 5 if (len == 0) len = buffer.Length - start; 6 int length = start + len; 7 if (length > buffer.Length) return null; 8 byte bcc = 0;// Initial value 9 for (int i = start; i < len; i++) 10 { 11 bcc ^= buffer[i]; 12 } 13 return new byte[] { bcc }; 14 }