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

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

              一體機(jī)讀寫器/分體式讀寫器AT指令CRC校驗(yàn)方法,暫時(shí)只有C#版本,C語言版本,Java語言版本、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;

                      }

                  }


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

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

              int bytes = CRC.crc16(input);

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

              (詢查模式應(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語言版本CRC:

              CRC16的C語言算法:

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

              }

              說明:

              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)算法工具類

               */

              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)閷W?,所以專業(yè)

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

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

              聯(lián)系我們

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

              400-807-2289

              daysr@qyswf.com

              周一至周六:8:30~20:00