RFID超高頻讀寫(xiě)器CRC16計(jì)算方法(.NET、C語(yǔ)言、Java語(yǔ)言、python版本)

          2022-03-09 15:00:36 lhqcool 9262

          一體機(jī)讀寫(xiě)器/分體式讀寫(xiě)器AT指令CRC校驗(yàn)方法,暫時(shí)只有C#版本,C語(yǔ)言版本,Java語(yǔ)言版本、python版本

          適用型號(hào):

          LT-DS302 DS312 DS309 DS310,LT-DS814 DS818 DS8112 DS8116,LT-DS509 DS512,LT-DS322

          C#版本CRC:

            public class CRC

              {

                  private static int POLYNOMIAL = 0x8408;

                  private static int PRESET_VALUE = 0xFFFF;


                  public static int crc16(string hex)

                  {

                      byte[] data = HexStringToByteArray(hex);

                      int current_crc_value = PRESET_VALUE;

                      for (int i = 0; i < data.Length; i++)

                      {

                          current_crc_value ^= data[i] & 0xFF;

                          for (int j = 0; j < 8; j++)

                          {

                              if ((current_crc_value & 1) != 0)

                              {

                                  current_crc_value = (current_crc_value >> 1) ^ POLYNOMIAL;

                              }

                              else

                              {

                                  current_crc_value = current_crc_value >> 1;

                              }

                          }

                      }

                      return current_crc_value;

                  }

                  //16進(jìn)制數(shù)組字符串轉(zhuǎn)換         

                  private static byte[] HexStringToByteArray(string s)

                  {

                      s = s.Replace(" ", "");

                      byte[] buffer = new byte[s.Length / 2];

                      for (int i = 0; i < s.Length; i += 2)

                          buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);

                      return buffer;

                  }

              }


          (詢(xún)查模式應(yīng)答格式)調(diào)用示例:

          string input = "1500010301010C300833B2DDD90140000000002A80BE"//讀寫(xiě)器AT指令返回值,也可用于指令發(fā)送校驗(yàn)CRC

          int bytes = CRC.crc16(input);

          // bytes=0;bytes等于0表示通過(guò),其他值不通過(guò)!

          (詢(xún)查模式應(yīng)答格式)拆分示例:

          Len:15

          Adr:00

          reComd:01

          Status:03

          ant:01

          Num:01

          EPC/TID長(zhǎng)度:0C

          EPC號(hào)或TID數(shù)據(jù):300833B2DDD9014000000000

          RSSI值:2A

          CRC-LSB:80

          CRC-MSB:BE



          實(shí)時(shí)模式輸入格式也相似,Statuss是0xee 就是實(shí)時(shí)模式回傳的數(shù)據(jù)。




          C語(yǔ)言版本CRC:

          CRC16的C語(yǔ)言算法:

          #include #include #include #include #define PRESET_VALUE 0xFFFF

          #define POLYNOMIAL  0x8408


          typedef  unsigned char byte;


          typedef union name{

              int len;

              unsigned char ucx;

          } name;



          unsigned int uiCrc16Cal(unsigned char const* pucY, unsigned char ucX)

          {

              unsigned char ucI, ucJ;

              unsigned short int  uiCrcValue = PRESET_VALUE;

              for (ucI = 0; ucI < ucX; ucI++)

              {

                  uiCrcValue = uiCrcValue ^ *(pucY + ucI);

                  for (ucJ = 0; ucJ < 8; ucJ++)

                  {

                      if (uiCrcValue & 0x0001)

                      {

                          uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL;

                      }

                      else

                      {

                          uiCrcValue = (uiCrcValue >> 1);

                      }

                  }

              }

              return uiCrcValue;

          }


          void hexToBytes(const std::string& hex, byte* bytes){

              int bytelen = hex.length()/2;

              std::string strByte;

              unsigned int n;

              for(int i = 0; i < bytelen; i++){

                  strByte = hex.substr(i*2, 2);

                  sscanf(strByte.c_str(), "%x", &n);

                  bytes[i]=n;

              }

          }



          int main()

          {

              std::string hex="1500010101010ce28011700000020cc282e26d84d652"

              int bytelen=hex.length()/2;

              byte *ptr=new byte[bytelen];

              hexToBytes(hex, ptr);


              unsigned int ret = uiCrc16Cal(ptr, bytelen);

                

              std::cout << ret << std::endl;

              delete [] ptr;

              return 0;

          }

          說(shuō)明:

          pucY是要計(jì)算CRC16的字符數(shù)組的入口(需轉(zhuǎn)換字節(jié)數(shù)組),ucX是字符數(shù)組中字符個(gè)數(shù)。

          上位機(jī)收到數(shù)據(jù)的時(shí)候,只要把收到的數(shù)據(jù)按以上算法進(jìn)行計(jì)算CRC16,結(jié)果為0x0000表明數(shù)據(jù)正確。

          言版本:


          package cn.longhaul.test;


          /**

           *  CRC16的校驗(yàn)算法工具類(lèi)

           */

          public class Crc16Util {


          /**

          * 一個(gè)字節(jié)包含位的數(shù)量 8

          */

          private static final int BITS_OF_BYTE = 8;

          /**

          * 多項(xiàng)式

          */

          private static final int POLYNOMIAL = 0x8408;

          /**

          * 初始值

          */

          private static final int INITIAL_VALUE = 0xFFFF;


          /**

          * CRC16 編碼

          *

          * @param bytes 編碼內(nèi)容

          * @return 編碼結(jié)果

          */

          public static int crc16(int[] bytes) {

          int res = INITIAL_VALUE;

          for (int data : bytes) {

          res = res ^ data;

          for (int i = 0; i < BITS_OF_BYTE; i++) {

          res = (res & 0x0001) == 1 ? (res >> 1) ^ POLYNOMIAL : res >> 1;

          }

          }

          return revert(res);

          }


          /**

          * 翻轉(zhuǎn)16位的高八位和低八位字節(jié)

          *

          * @param src 翻轉(zhuǎn)數(shù)字

          * @return 翻轉(zhuǎn)結(jié)果

          */

          private static int revert(int src) {

          int lowByte = (src & 0xFF00) >> 8;

          int highByte = (src & 0x00FF) << 8;

          return lowByte | highByte;

          }



          /** 十六進(jìn)制轉(zhuǎn)為IntBytes

          * @param s 十六進(jìn)制串

          * @return  int[] bytes

          */

          public static int[] hexString2IntBytes(String s) {

          int[] bytes;

          bytes = new int[s.length() / 2];

          for (int i = 0; i < bytes.length; i++) {

          bytes[i] = (int) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);

          }

          return bytes;

          }


          public static void main(String[] args) throws Exception {

          int[] data = Crc16Util.hexString2IntBytes("18010206E28011700000020A7D001A0701000600000000");

          final int res = Crc16Util.crc16(data);

          final String hex = Integer.toHexString(res);

          System.out.print(hex);

          }


          }




          python版本:

          # -*-coding:utf-8-*-


          #  多項(xiàng)式 0x8408

          POLYNOMIAL = 0x8408

          # 初始值為:0xFFFF

          INITIAL_VALUE = 0xFFFF



          def crc16(dataarray):

              datalength = int(len(dataarray) / 2)

              datalist = [None] * datalength

              index = 0

              try:

                  for index in range(datalength):

                      item = dataarray[index * 2:index * 2 + 2]

                      datalist[index] = int(item, 16)

                  res = INITIAL_VALUE

                  for data in datalist:

                      res = res ^ data

                      for index in range(8):

                          if res & 0x0001 == 1:

                              res >>= 1

                              res ^= POLYNOMIAL

                          else:

                              res >>= 1

                  lowbyte = (res & 0xFF00) >> 8

                  highbyte = (res & 0x00FF) << 8

                  res = lowbyte | highbyte

                  return res

              except ValueError as err:

                  print(u'第{0}個(gè)數(shù)據(jù){1}輸入有誤'.format(index, datalist[index]).encode('utf-8'))

                  print(err)



          if __name__ == '__main__':

              data_string = '18FF0206E28011700000020A7D001A0702000800000000'  # 16進(jìn)制輸入的數(shù)據(jù)流

              print('數(shù)據(jù) :"{0:s}"對(duì)應(yīng)的CRC16檢驗(yàn)碼為:{1:04X}'.format(data_string, crc16(data_string)))

              data_string = '18010206E28011700000020A7D001A0701000600000000'  # 16進(jìn)制輸入的數(shù)據(jù)流

              print('數(shù)據(jù) :"{0:s}"對(duì)應(yīng)的CRC16檢驗(yàn)碼為:{1:04X}'.format(data_string, crc16(data_string)))

              data_string = '06FF010400'  # 16進(jìn)制輸入的數(shù)據(jù)流

              print('數(shù)據(jù) :"{0:s}"對(duì)應(yīng)的CRC16檢驗(yàn)碼為:{1:04X}'.format(data_string, crc16(data_string)))


          因?yàn)閷?zhuān)注,所以專(zhuān)業(yè)

          廣東靈天智能科技有限公司是一家rfid電子標(biāo)簽生產(chǎn)廠家,自成立以來(lái)一直致力于超高頻RFID解決方案生產(chǎn)服務(wù)商擁有自主生產(chǎn)、研發(fā)、銷(xiāo)售體系,其rfid電子標(biāo)簽,rfid打印機(jī),超高頻讀寫(xiě)器等產(chǎn)品遠(yuǎn)銷(xiāo)國(guó)內(nèi)外。在惠州設(shè)有工廠擔(dān)任生產(chǎn)部分工作,普及應(yīng)用領(lǐng)域:電力、銀行、鋼鐵、有色、零售、制造業(yè)、服裝、物流、電商、汽車(chē)配件等其他...

          rfid電子標(biāo)簽展示

          聯(lián)系我們

          廣東省東莞市中堂鎮(zhèn)潢涌工業(yè)橫路2號(hào)7棟8層

          400-807-2289

          daysr@qyswf.com

          7*24小時(shí)服務(wù)