CRC16-ccitt-false 解析每一个号码段的值
-
数据准备
加密前:6011qwertyuiopa62440007db2a65b0306qrcode043339912211117000000016304
CRC16-ccitt-false加密后:4023(网上有加密工具类,也有线上计算工具,如下图)
拼接在一起:6011qwertyuiopa62440007db2a65b0306qrcode0433399122111170000000163044023

-
我们该如何解析出6011qwertyuiopa62440007db2a65b0306qrcode0419399122111170000000163044023这里面每个号码段对应的值呢?由于键都是两位,值的长度规定不超过99,也是两位,可以通过一个简单的递归解析出每个键对应的值。
/*** crc16-ccitt-false加密工具*/
public class CRC16Util {/*** crc16-ccitt-false加/解密(四字节)** @param s 需要加密的字符串* @return*/public static String crc16(String s) {byte[] bytes = s.getBytes();int crc = crc16(bytes, bytes.length);//结果转换为16进制String result = Integer.toHexString(crc).toUpperCase();if (result.length() != 4) {StringBuffer sb = new StringBuffer("0000");result = sb.replace(4 - result.length(), 4, result).toString();}return result;}/*** crc16-ccitt-false加/解密(四字节)** @param bytes -字节数组* @return*/public static int crc16(byte[] bytes, int len) {int crc = 0xFFFF;for (int j = 0; j < len; j++) {crc = ((crc >>> 8) | (crc << 8)) & 0xffff;crc ^= (bytes[j] & 0xff);// byte to int, trunc signcrc ^= ((crc & 0xff) >> 4);crc ^= (crc << 12) & 0xffff;crc ^= ((crc & 0xFF) << 5) & 0xffff;}crc &= 0xffff;return crc;}/*** 递归按[ID位--值对]拆解二维码** @param s 下一段* @param map 保存ID--值对*/public static void stringSplit(String s, Map<String, String> map) {// 每次进来取前两位 ID位String raw1 = s.substring(0, 2);// 长度位String raw2 = s.substring(2, 4);int value_length = Integer.parseInt(raw2);// 值String value = s.substring(4, 4 + value_length);// 返回ID--值 对map.put(raw1, value);// 下一段String nextStr = s.substring(4 + value_length, s.length());if (!StringUtils.isEmpty(nextStr)) {// 递归stringSplit(nextStr, map);}}/*** @param args 测试*/public static void main(String[] args) {// 源串String s = "6011qwertyuiopa62440007db2a65b0306qrcode041939912211117000000016304";// 计算CRC值System.out.println(crc16(s));// 解析开始// 1、校验CRC串是否合法s = s + crc16(s); // 拼接在一起System.out.println(s);// 校验crcint length = s.length();String crcStr = s.substring(length - 4); // crc校验码 字符串后4位String raw = s.substring(0, length - 4); // crc源串 字符串去除后4位Boolean checkCrc = crc16(raw).equals(crcStr);System.out.println(checkCrc);// 2、递归解析if (checkCrc) {Map<String, String> map = new HashMap<>();stringSplit(s, map);System.out.println(map);}Map<String, String> map = new HashMap<>();String ss = "0007db2a65b0306qrcode04193991221111700000001";stringSplit(ss, map);System.out.println(map);}
}
Main方法中结果的打印:
4023
6011qwertyuiopa62440007db2a65b0306qrcode0419399122111170000000163044023
true
{60=qwertyuiopa, 62=0007db2a65b0306qrcode04193991221111700000001, 63=4023}
- 我们最终得到了源串每个键对应的值:{60=qwertyuiopa, 62=0007db2a65b0306qrcode04333991221111700000001, 63=0D74}。如果还想继续解析出62-00,62-03,62-04对应的值,可以再次调用递归方法stringSplit,得到{00=db2a65b, 03=qrcode, 04=3991221111700000001}















