C#,Java,C -循环冗余检验:CRC-16-CCITT查表法

简介:

C#代码

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 namespace TestCRC
  7 {
  8     /// <summary>  
  9     /// 循环冗余检验:CRC-16-CCITT查表法  
 10     /// </summary>  
 11     public static partial class CRCITU
 12     {
 13         /// <summary>  
 14         /// 计算给定长度数据的16位CRC  
 15         /// </summary>  
 16         /// <param name="data">要计算CRC的字节数组</param>  
 17         /// <returns>CRC值</returns>  
 18         public static UInt16 GetCrc16(Byte[] data)
 19         {   // 初始化  
 20             Int32 High = 0xFF;  // 高字节  
 21             Int32 Low = 0xFF;   // 低字节  
 22             if (data != null)
 23             {
 24                 foreach (Byte b in data)
 25                 {
 26                     Int32 Index = Low ^ b;
 27                     Low = High ^ CRC16TABLE_LO[Index];
 28                     High = CRC16TABLE_HI[Index];
 29                 }
 30             }
 31             return (UInt16)(~((High << 8) + Low));    // 取反  
 32         }
 33 
 34         /// <summary>  
 35         /// 检查给定长度数据的16位CRC是否正确  
 36         /// </summary>  
 37         /// <param name="data">要校验的字节数组</param>  
 38         /// <returns>  
 39         ///     true:正确  
 40         ///     false:错误  
 41         /// </returns>  
 42         /// <reamrks>  
 43         /// 字节数组最后2个字节为校验码,且低字节在前面,高字节在后面  
 44         /// </reamrks>  
 45         public static Boolean IsCrc16Good(Byte[] data)
 46         {
 47             // 初始化  
 48             Int32 High = 0xFF;
 49             Int32 Low = 0xFF;
 50             if (data != null)
 51             {
 52                 foreach (Byte b in data)
 53                 {
 54                     Int32 Index = Low ^ b;
 55                     Low = High ^ CRC16TABLE_LO[Index];
 56                     High = CRC16TABLE_HI[Index];
 57                 }
 58             }
 59 
 60             return (High == 0xF0 && Low == 0xB8);
 61         }
 62 
 63         /// <summary>  
 64         /// CRC16查找表高字节  
 65         /// </summary>  
 66         private static readonly Byte[] CRC16TABLE_HI =  
 67         {  
 68             0x00, 0x11, 0x23, 0x32, 0x46, 0x57, 0x65, 0x74, 0x8C, 0x9D, 0xAF, 0xBE, 0xCA, 0xDB, 0xE9, 0xF8,  
 69             0x10, 0x01, 0x33, 0x22, 0x56, 0x47, 0x75, 0x64, 0x9C, 0x8D, 0xBF, 0xAE, 0xDA, 0xCB, 0xF9, 0xE8,  
 70             0x21, 0x30, 0x02, 0x13, 0x67, 0x76, 0x44, 0x55, 0xAD, 0xBC, 0x8E, 0x9F, 0xEB, 0xFA, 0xC8, 0xD9,  
 71             0x31, 0x20, 0x12, 0x03, 0x77, 0x66, 0x54, 0x45, 0xBD, 0xAC, 0x9E, 0x8F, 0xFB, 0xEA, 0xD8, 0xC9,  
 72             0x42, 0x53, 0x61, 0x70, 0x04, 0x15, 0x27, 0x36, 0xCE, 0xDF, 0xED, 0xFC, 0x88, 0x99, 0xAB, 0xBA,  
 73             0x52, 0x43, 0x71, 0x60, 0x14, 0x05, 0x37, 0x26, 0xDE, 0xCF, 0xFD, 0xEC, 0x98, 0x89, 0xBB, 0xAA,  
 74             0x63, 0x72, 0x40, 0x51, 0x25, 0x34, 0x06, 0x17, 0xEF, 0xFE, 0xCC, 0xDD, 0xA9, 0xB8, 0x8A, 0x9B,  
 75             0x73, 0x62, 0x50, 0x41, 0x35, 0x24, 0x16, 0x07, 0xFF, 0xEE, 0xDC, 0xCD, 0xB9, 0xA8, 0x9A, 0x8B,  
 76             0x84, 0x95, 0xA7, 0xB6, 0xC2, 0xD3, 0xE1, 0xF0, 0x08, 0x19, 0x2B, 0x3A, 0x4E, 0x5F, 0x6D, 0x7C,  
 77             0x94, 0x85, 0xB7, 0xA6, 0xD2, 0xC3, 0xF1, 0xE0, 0x18, 0x09, 0x3B, 0x2A, 0x5E, 0x4F, 0x7D, 0x6C,  
 78             0xA5, 0xB4, 0x86, 0x97, 0xE3, 0xF2, 0xC0, 0xD1, 0x29, 0x38, 0x0A, 0x1B, 0x6F, 0x7E, 0x4C, 0x5D,  
 79             0xB5, 0xA4, 0x96, 0x87, 0xF3, 0xE2, 0xD0, 0xC1, 0x39, 0x28, 0x1A, 0x0B, 0x7F, 0x6E, 0x5C, 0x4D,  
 80             0xC6, 0xD7, 0xE5, 0xF4, 0x80, 0x91, 0xA3, 0xB2, 0x4A, 0x5B, 0x69, 0x78, 0x0C, 0x1D, 0x2F, 0x3E,  
 81             0xD6, 0xC7, 0xF5, 0xE4, 0x90, 0x81, 0xB3, 0xA2, 0x5A, 0x4B, 0x79, 0x68, 0x1C, 0x0D, 0x3F, 0x2E,  
 82             0xE7, 0xF6, 0xC4, 0xD5, 0xA1, 0xB0, 0x82, 0x93, 0x6B, 0x7A, 0x48, 0x59, 0x2D, 0x3C, 0x0E, 0x1F,  
 83             0xF7, 0xE6, 0xD4, 0xC5, 0xB1, 0xA0, 0x92, 0x83, 0x7B, 0x6A, 0x58, 0x49, 0x3D, 0x2C, 0x1E, 0x0F 
 84         };
 85 
 86         /// <summary>  
 87         /// CRC16查找表低字节  
 88         /// </summary>  
 89         private static readonly Byte[] CRC16TABLE_LO =   
 90         {  
 91             0x00, 0x89, 0x12, 0x9B, 0x24, 0xAD, 0x36, 0xBF, 0x48, 0xC1, 0x5A, 0xD3, 0x6C, 0xE5, 0x7E, 0xF7,  
 92             0x81, 0x08, 0x93, 0x1A, 0xA5, 0x2C, 0xB7, 0x3E, 0xC9, 0x40, 0xDB, 0x52, 0xED, 0x64, 0xFF, 0x76,  
 93             0x02, 0x8B, 0x10, 0x99, 0x26, 0xAF, 0x34, 0xBD, 0x4A, 0xC3, 0x58, 0xD1, 0x6E, 0xE7, 0x7C, 0xF5,  
 94             0x83, 0x0A, 0x91, 0x18, 0xA7, 0x2E, 0xB5, 0x3C, 0xCB, 0x42, 0xD9, 0x50, 0xEF, 0x66, 0xFD, 0x74,  
 95             0x04, 0x8D, 0x16, 0x9F, 0x20, 0xA9, 0x32, 0xBB, 0x4C, 0xC5, 0x5E, 0xD7, 0x68, 0xE1, 0x7A, 0xF3,  
 96             0x85, 0x0C, 0x97, 0x1E, 0xA1, 0x28, 0xB3, 0x3A, 0xCD, 0x44, 0xDF, 0x56, 0xE9, 0x60, 0xFB, 0x72,  
 97             0x06, 0x8F, 0x14, 0x9D, 0x22, 0xAB, 0x30, 0xB9, 0x4E, 0xC7, 0x5C, 0xD5, 0x6A, 0xE3, 0x78, 0xF1,  
 98             0x87, 0x0E, 0x95, 0x1C, 0xA3, 0x2A, 0xB1, 0x38, 0xCF, 0x46, 0xDD, 0x54, 0xEB, 0x62, 0xF9, 0x70,  
 99             0x08, 0x81, 0x1A, 0x93, 0x2C, 0xA5, 0x3E, 0xB7, 0x40, 0xC9, 0x52, 0xDB, 0x64, 0xED, 0x76, 0xFF,  
100             0x89, 0x00, 0x9B, 0x12, 0xAD, 0x24, 0xBF, 0x36, 0xC1, 0x48, 0xD3, 0x5A, 0xE5, 0x6C, 0xF7, 0x7E,  
101             0x0A, 0x83, 0x18, 0x91, 0x2E, 0xA7, 0x3C, 0xB5, 0x42, 0xCB, 0x50, 0xD9, 0x66, 0xEF, 0x74, 0xFD,  
102             0x8B, 0x02, 0x99, 0x10, 0xAF, 0x26, 0xBD, 0x34, 0xC3, 0x4A, 0xD1, 0x58, 0xE7, 0x6E, 0xF5, 0x7C,  
103             0x0C, 0x85, 0x1E, 0x97, 0x28, 0xA1, 0x3A, 0xB3, 0x44, 0xCD, 0x56, 0xDF, 0x60, 0xE9, 0x72, 0xFB,  
104             0x8D, 0x04, 0x9F, 0x16, 0xA9, 0x20, 0xBB, 0x32, 0xC5, 0x4C, 0xD7, 0x5E, 0xE1, 0x68, 0xF3, 0x7A,  
105             0x0E, 0x87, 0x1C, 0x95, 0x2A, 0xA3, 0x38, 0xB1, 0x46, 0xCF, 0x54, 0xDD, 0x62, 0xEB, 0x70, 0xF9,  
106             0x8F, 0x06, 0x9D, 0x14, 0xAB, 0x22, 0xB9, 0x30, 0xC7, 0x4E, 0xD5, 0x5C, 0xE3, 0x6A, 0xF1, 0x78  
107         };
108     }  
109 }
复制代码

 

Java代码

复制代码
  1 import com.example.utils.BitConverter;
  2 
  3 
  4 
  5 /**
  6  * 循环冗余检验:CRC-16-CCITT查表法
  7  */
  8 public final class CRC16 {
  9     
 10     public static void main(String[] args) {
 11         short result=CRC16.GetCrc16(new byte[]{1,2,3});
 12         System.out.println(Integer.toHexString(result));
 13     }
 14     /**
 15      * 计算给定长度数据的16位CRC
 16      * 
 17      * @param data
 18      *            要计算CRC的字节数组
 19      * @return CRC值
 20      */
 21     public static short GetCrc16(byte[] data) { // 初始化
 22         int High = 0xFF; // 高字节
 23         int Low = 0xFF; // 低字节
 24         if (data != null) {
 25             for (byte b : data) {
 26                 int Index = Low ^ b;
 27                 Low = High ^ CRC16TABLE_LO[Index];
 28                 High = CRC16TABLE_HI[Index];
 29             }
 30         }
 31         return (short) (~((High << 8) + Low)); // 取反
 32     }
 33 
 34     /**
 35      * 检查给定长度数据的16位CRC是否正确
 36      * 
 37      * @param data
 38      *            要校验的字节数组
 39      * @return true:正确 false:错误
 40      * 
 41      *         <reamrks> 字节数组最后2个字节为校验码,且低字节在前面,高字节在后面 </reamrks>
 42      */
 43     public static boolean IsCrc16Good(byte[] data) {
 44         // 初始化
 45         int High = 0xFF;
 46         int Low = 0xFF;
 47         if (data != null) {
 48             for (byte b : data) {
 49                 int Index = Low ^ b;
 50                 Low = High ^ CRC16TABLE_LO[Index];
 51                 High = CRC16TABLE_HI[Index];
 52             }
 53         }
 54 
 55         return (High == 0xF0 && Low == 0xB8);
 56     }
 57 
 58     /**
 59      * CRC16查找表高字节
 60      */
 61     private static final int[] CRC16TABLE_HI = { 0x00, 0x11, 0x23, 0x32, 0x46,
 62             0x57, 0x65, 0x74, 0x8C, 0x9D, 0xAF, 0xBE, 0xCA, 0xDB, 0xE9, 0xF8,
 63             0x10, 0x01, 0x33, 0x22, 0x56, 0x47, 0x75, 0x64, 0x9C, 0x8D, 0xBF,
 64             0xAE, 0xDA, 0xCB, 0xF9, 0xE8, 0x21, 0x30, 0x02, 0x13, 0x67, 0x76,
 65             0x44, 0x55, 0xAD, 0xBC, 0x8E, 0x9F, 0xEB, 0xFA, 0xC8, 0xD9, 0x31,
 66             0x20, 0x12, 0x03, 0x77, 0x66, 0x54, 0x45, 0xBD, 0xAC, 0x9E, 0x8F,
 67             0xFB, 0xEA, 0xD8, 0xC9, 0x42, 0x53, 0x61, 0x70, 0x04, 0x15, 0x27,
 68             0x36, 0xCE, 0xDF, 0xED, 0xFC, 0x88, 0x99, 0xAB, 0xBA, 0x52, 0x43,
 69             0x71, 0x60, 0x14, 0x05, 0x37, 0x26, 0xDE, 0xCF, 0xFD, 0xEC, 0x98,
 70             0x89, 0xBB, 0xAA, 0x63, 0x72, 0x40, 0x51, 0x25, 0x34, 0x06, 0x17,
 71             0xEF, 0xFE, 0xCC, 0xDD, 0xA9, 0xB8, 0x8A, 0x9B, 0x73, 0x62, 0x50,
 72             0x41, 0x35, 0x24, 0x16, 0x07, 0xFF, 0xEE, 0xDC, 0xCD, 0xB9, 0xA8,
 73             0x9A, 0x8B, 0x84, 0x95, 0xA7, 0xB6, 0xC2, 0xD3, 0xE1, 0xF0, 0x08,
 74             0x19, 0x2B, 0x3A, 0x4E, 0x5F, 0x6D, 0x7C, 0x94, 0x85, 0xB7, 0xA6,
 75             0xD2, 0xC3, 0xF1, 0xE0, 0x18, 0x09, 0x3B, 0x2A, 0x5E, 0x4F, 0x7D,
 76             0x6C, 0xA5, 0xB4, 0x86, 0x97, 0xE3, 0xF2, 0xC0, 0xD1, 0x29, 0x38,
 77             0x0A, 0x1B, 0x6F, 0x7E, 0x4C, 0x5D, 0xB5, 0xA4, 0x96, 0x87, 0xF3,
 78             0xE2, 0xD0, 0xC1, 0x39, 0x28, 0x1A, 0x0B, 0x7F, 0x6E, 0x5C, 0x4D,
 79             0xC6, 0xD7, 0xE5, 0xF4, 0x80, 0x91, 0xA3, 0xB2, 0x4A, 0x5B, 0x69,
 80             0x78, 0x0C, 0x1D, 0x2F, 0x3E, 0xD6, 0xC7, 0xF5, 0xE4, 0x90, 0x81,
 81             0xB3, 0xA2, 0x5A, 0x4B, 0x79, 0x68, 0x1C, 0x0D, 0x3F, 0x2E, 0xE7,
 82             0xF6, 0xC4, 0xD5, 0xA1, 0xB0, 0x82, 0x93, 0x6B, 0x7A, 0x48, 0x59,
 83             0x2D, 0x3C, 0x0E, 0x1F, 0xF7, 0xE6, 0xD4, 0xC5, 0xB1, 0xA0, 0x92,
 84             0x83, 0x7B, 0x6A, 0x58, 0x49, 0x3D, 0x2C, 0x1E, 0x0F };
 85 
 86     /**
 87      * CRC16查找表低字节
 88      */
 89     private static final int[] CRC16TABLE_LO = { 0x00, 0x89, 0x12, 0x9B, 0x24,
 90             0xAD, 0x36, 0xBF, 0x48, 0xC1, 0x5A, 0xD3, 0x6C, 0xE5, 0x7E, 0xF7,
 91             0x81, 0x08, 0x93, 0x1A, 0xA5, 0x2C, 0xB7, 0x3E, 0xC9, 0x40, 0xDB,
 92             0x52, 0xED, 0x64, 0xFF, 0x76, 0x02, 0x8B, 0x10, 0x99, 0x26, 0xAF,
 93             0x34, 0xBD, 0x4A, 0xC3, 0x58, 0xD1, 0x6E, 0xE7, 0x7C, 0xF5, 0x83,
 94             0x0A, 0x91, 0x18, 0xA7, 0x2E, 0xB5, 0x3C, 0xCB, 0x42, 0xD9, 0x50,
 95             0xEF, 0x66, 0xFD, 0x74, 0x04, 0x8D, 0x16, 0x9F, 0x20, 0xA9, 0x32,
 96             0xBB, 0x4C, 0xC5, 0x5E, 0xD7, 0x68, 0xE1, 0x7A, 0xF3, 0x85, 0x0C,
 97             0x97, 0x1E, 0xA1, 0x28, 0xB3, 0x3A, 0xCD, 0x44, 0xDF, 0x56, 0xE9,
 98             0x60, 0xFB, 0x72, 0x06, 0x8F, 0x14, 0x9D, 0x22, 0xAB, 0x30, 0xB9,
 99             0x4E, 0xC7, 0x5C, 0xD5, 0x6A, 0xE3, 0x78, 0xF1, 0x87, 0x0E, 0x95,
100             0x1C, 0xA3, 0x2A, 0xB1, 0x38, 0xCF, 0x46, 0xDD, 0x54, 0xEB, 0x62,
101             0xF9, 0x70, 0x08, 0x81, 0x1A, 0x93, 0x2C, 0xA5, 0x3E, 0xB7, 0x40,
102             0xC9, 0x52, 0xDB, 0x64, 0xED, 0x76, 0xFF, 0x89, 0x00, 0x9B, 0x12,
103             0xAD, 0x24, 0xBF, 0x36, 0xC1, 0x48, 0xD3, 0x5A, 0xE5, 0x6C, 0xF7,
104             0x7E, 0x0A, 0x83, 0x18, 0x91, 0x2E, 0xA7, 0x3C, 0xB5, 0x42, 0xCB,
105             0x50, 0xD9, 0x66, 0xEF, 0x74, 0xFD, 0x8B, 0x02, 0x99, 0x10, 0xAF,
106             0x26, 0xBD, 0x34, 0xC3, 0x4A, 0xD1, 0x58, 0xE7, 0x6E, 0xF5, 0x7C,
107             0x0C, 0x85, 0x1E, 0x97, 0x28, 0xA1, 0x3A, 0xB3, 0x44, 0xCD, 0x56,
108             0xDF, 0x60, 0xE9, 0x72, 0xFB, 0x8D, 0x04, 0x9F, 0x16, 0xA9, 0x20,
109             0xBB, 0x32, 0xC5, 0x4C, 0xD7, 0x5E, 0xE1, 0x68, 0xF3, 0x7A, 0x0E,
110             0x87, 0x1C, 0x95, 0x2A, 0xA3, 0x38, 0xB1, 0x46, 0xCF, 0x54, 0xDD,
111             0x62, 0xEB, 0x70, 0xF9, 0x8F, 0x06, 0x9D, 0x14, 0xAB, 0x22, 0xB9,
112             0x30, 0xC7, 0x4E, 0xD5, 0x5C, 0xE3, 0x6A, 0xF1, 0x78 };
113 }
复制代码

 

C代码

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 namespace GovConsoleSuperior.Common
  7 {
  8     /// <summary>  
  9     /// 循环冗余检验:CRC-16-CCITT查表法  
 10     /// </summary>  
 11     public static partial class CRCITU
 12     {
 13         /// <summary>  
 14         /// 计算给定长度数据的16位CRC  
 15         /// </summary>  
 16         /// <param name="data">要计算CRC的字节数组</param>  
 17         /// <returns>CRC值</returns>  
 18         public static byte[] GetCrc16(Byte[] buffer)
 19         {
 20             int crc = 0;
 21             int l = buffer.Length;
 22             for (int i = 0; i < l; i++)
 23             {
 24                 int by = (crc >> 8) & 0xff;
 25                 crc = (crc & 0xffff) << 8;
 26                 crc = (crc ^ table[(buffer[i] ^ by) & 0xff]) & 0xffff;
 27             }
 28 
 29             return GetCRCBytes(crc);
 30 
 31         }
 32         /// <summary>
 33         /// 获取CRC字节数组
 34         /// </summary>
 35         /// <param name="crc">整形的CRC</param>
 36         /// <returns>两字节的CRC字节数组</returns>
 37         private static byte[] GetCRCBytes(int crc)
 38         {
 39             byte[] result = BitConverter.GetBytes(crc);
 40             Array.Resize(ref result, 2);                //只截取前面两个byte字节
 41 
 42             return result;
 43         }
 44 
 45 
 46 
 47 
 48         static int[] table = {
 49             0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a,
 50             0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
 51             0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6,
 52             0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672,
 53             0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
 54             0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af,
 55             0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd,
 56             0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03,
 57             0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5,
 58             0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
 59             0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004,
 60             0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290,
 61             0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c,
 62             0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
 63             0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c,
 64             0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1,
 65             0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37,
 66             0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
 67             0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b,
 68             0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 
 69             };
 70 
 71         /// <summary>  
 72         /// 检查给定长度数据的16位CRC是否正确  
 73         /// </summary>  
 74         /// <param name="FromHeadToVaild">要校验的字节数组</param>  
 75         /// <returns>  
 76         ///     true:正确  
 77         ///     false:错误  
 78         /// </returns>  
 79         /// <reamrks>  
 80         /// 字节数组最后2个字节为校验码
 81         /// </reamrks>  
 82         public static Boolean IsCrc16Good(Byte[] FromHeadToCRC)
 83         {
 84             byte[] FromHeadToVaild = GetHeadToVaildData(FromHeadToCRC);     //头到验证域
 85             byte[] CRCFromPackage = GetCRCFromPackage(FromHeadToCRC);       //获取客户端传来的包中的CRC数组   
 86             byte[] TrueCRCValue = GetCrc16(FromHeadToVaild);                //获取客户端传来的包应该的CRC数组
 87             return BytesEquals(CRCFromPackage, TrueCRCValue);
 88         }
 89         /// <summary>
 90         /// 比较两个字节数组是否相等
 91         /// </summary>
 92         /// <param name="b1">byte数组1</param>
 93         /// <param name="b2">byte数组2</param>
 94         /// <returns>是否相等</returns>
 95         private static bool BytesEquals(byte[] b1, byte[] b2)
 96         {
 97             if (b1.Length != b2.Length) return false;
 98             if (b1 == null || b2 == null) return false;
 99             for (int i = 0; i < b1.Length; i++)
100                 if (b1[i] != b2[i])
101                     return false;
102             return true;
103         }
104 
105 
106         /// <summary>
107         /// 获取客户端传来的包中的CRC数组
108         /// </summary>
109         /// <param name="FromHeadToCRC">从头到CRC校验域</param>
110         /// <returns>CRC数组</returns>
111         private static byte[] GetCRCFromPackage(byte[] FromHeadToCRC)
112         {
113             int iCRCLen = 2;                                                             //因为CRC占两个字节
114             byte[] CRCValue = new byte[iCRCLen];                                          //用于存储包中CRC的值
115             int i;
116             for (i = 0; i < iCRCLen; i++)                                                 //得到一个临时字节数组    
117             {
118                 CRCValue[i] = FromHeadToCRC[FromHeadToCRC.Length - iCRCLen + i];
119             }
120             return CRCValue;
121         }
122         /// <summary>
123         /// 得到从头到有效数据的数据(不包含CRC验证域)
124         /// </summary>
125         /// <param name="FromHeadToCRC"></param>
126         /// <returns></returns>
127         private static byte[] GetHeadToVaildData(byte[] FromHeadToCRC)
128         {
129             int iLengh = FromHeadToCRC.Length - 2;               //因为CRC占两个字节
130             byte[] FromHeadToVaild = new byte[iLengh];       //用于存储包头到有效数据域的bytes
131             int i;
132             for (i = 0; i < iLengh; i++)                     //得到一个临时字节数组    
133             {
134                 FromHeadToVaild[i] = FromHeadToCRC[i];
135             }
136             return FromHeadToVaild;
137 
138         }
139 
140     }
141 
142 }
复制代码

 


作者:kissazi2 
出处:http://www.cnblogs.com/kissazi2/ 
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/kissazi2/p/3341461.html

目录
相关文章
|
Java
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
448 4
|
3月前
|
Java
Java编程:理解while循环的使用
总结而言, 使用 while 迴圈可以有效解决需要多次重复操作直至特定條件被触发才停止執行任务场景下问题; 它简单、灵活、易于实现各种逻辑控制需求但同时也要注意防止因邏各错误导致無限迁璇発生及及時處理可能発生异常以确保程序稳定运作。
336 0
|
安全 编译器 程序员
C# 中 foreach 循环和 for 循环深度比较
为什么建议你多数情况下使用 foreach 进行遍历循环?看完你就明白了
328 5
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
271 2
|
8月前
|
传感器 安全 Java
《从头开始学java,一天一个知识点》之:循环结构:for与while循环的使用场景
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白
232 22
|
10月前
|
Java
Java快速入门之判断与循环
本文介绍了编程中的流程控制语句,主要包括顺序结构、判断结构(if语句和switch语句)以及循环结构(for、while和do...while)。通过这些语句可以精确控制程序的执行流程。if语句有三种格式,分别用于简单条件判断、二选一判断和多条件判断。switch语句适用于有限个离散值的选择判断,而循环结构则用于重复执行某段代码,其中for循环适合已知次数的情况,while循环适合未知次数但有明确结束条件的情况,do...while则是先执行后判断。文中还提供了多个示例和练习,帮助读者理解并掌握这些重要的编程概念。
|
存储 Java
|
开发框架 Java .NET
C#与Java
在动态且不断发展的软件开发世界中,Java 和 C# 是两个巨头,每个都有自己独特的优势、理念和生态系统。本文深入比较了 Java 和 C#,探讨了它们的历史背景、语言特性、性能指标、跨平台功能等。
391 19
C#与Java
|
12月前
|
Java 程序员 API
Java循环操作哪个快?
本文探讨了Java中Stream API与传统for循环的性能对比及适用场景。作者通过实际案例分析,指出在某些情况下,过度使用Stream API会导致代码可读性和维护性下降。测试结果显示,在数据量较小的情况下,普通for循环的性能优于Stream API,尤其是在涉及多次类似操作时。因此,建议在开发中根据具体需求选择合适的遍历方式,以提高代码的可读性和性能。
266 5
Java循环操作哪个快?