| | |
| | | private transient byte[] encodeBytes = null; |
| | | private transient byte[] unusedBytes = null; |
| | | |
| | | @SuppressWarnings({"unchecked", "rawtypes"}) |
| | | public static <T extends Struct> T decode(Class<? extends Struct> cls, byte[] bytes) throws Exception { |
| | | Struct instance = cls.newInstance(); |
| | | return instance.decode(bytes); |
| | | } |
| | | |
| | | // 字节数组 ===>> 转为十六进制字符串 |
| | | public static String toHex(byte[] bytes) { |
| | | StringBuilder buf = new StringBuilder(bytes.length * 2); |
| | | for (byte b : bytes) { // 使用String的format方法进行转换 |
| | | buf.append(String.format("%02x", b & 0xff)); |
| | | } |
| | | return buf.toString().toUpperCase(); |
| | | } |
| | | |
| | | public static byte[] toBytes(String str) { |
| | | if (str == null || str.trim().equals("")) return new byte[0]; |
| | | byte[] bytes = new byte[str.length() / 2]; |
| | | for (int i = 0; i < str.length() / 2; i++) { |
| | | String subStr = str.substring(i * 2, i * 2 + 2); |
| | | bytes[i] = (byte) Integer.parseInt(subStr, 16); |
| | | } |
| | | return bytes; |
| | | } |
| | | |
| | | /** |
| | | * @功能: BCD码转为10进制串(阿拉伯数据) |
| | | * @参数: BCD码 |
| | | * @结果: 10进制串 |
| | | */ |
| | | public static String bcd2Str(byte[] bytes) { |
| | | StringBuffer temp = new StringBuffer(bytes.length * 2); |
| | | for (int i = 0; i < bytes.length; i++) { |
| | | temp.append((byte) ((bytes[i] & 0xf0) >>> 4)); |
| | | temp.append((byte) (bytes[i] & 0x0f)); |
| | | } |
| | | return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp |
| | | .toString().substring(1) : temp.toString(); |
| | | } |
| | | |
| | | /** |
| | | * @功能: 10进制串转为BCD码 |
| | | * @参数: 10进制串 |
| | | * @结果: BCD码 |
| | | */ |
| | | public static byte[] str2Bcd(String asc) { |
| | | int len = asc.length(); |
| | | int mod = len % 2; |
| | | if (mod != 0) { |
| | | asc = "0" + asc; |
| | | len = asc.length(); |
| | | } |
| | | byte abt[] = new byte[len]; |
| | | if (len >= 2) { |
| | | len = len / 2; |
| | | } |
| | | byte bbt[] = new byte[len]; |
| | | abt = asc.getBytes(); |
| | | int j, k; |
| | | for (int p = 0; p < asc.length() / 2; p++) { |
| | | if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) { |
| | | j = abt[2 * p] - '0'; |
| | | } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) { |
| | | j = abt[2 * p] - 'a' + 0x0a; |
| | | } else { |
| | | j = abt[2 * p] - 'A' + 0x0a; |
| | | } |
| | | if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) { |
| | | k = abt[2 * p + 1] - '0'; |
| | | } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) { |
| | | k = abt[2 * p + 1] - 'a' + 0x0a; |
| | | } else { |
| | | k = abt[2 * p + 1] - 'A' + 0x0a; |
| | | } |
| | | int a = (j << 4) + k; |
| | | byte b = (byte) a; |
| | | bbt[p] = b; |
| | | } |
| | | return bbt; |
| | | } |
| | | |
| | | public static byte getXor(byte[] datas, int start, int end) { |
| | | byte temp = datas[start]; |
| | | for (int i = start + 1; i < end; i++) { |
| | | temp ^= datas[i]; |
| | | } |
| | | return temp; |
| | | } |
| | | |
| | | /** |
| | | * 求校验和的算法 |
| | | * @param b 需要求校验和的字节数组 |
| | | * @return 校验和 |
| | | */ |
| | | public static byte sumCheck(byte[] b, int start, int end) { |
| | | int sum = 0; |
| | | for (int i = start; i < end; i++) { |
| | | sum = sum + b[i]; |
| | | } |
| | | return (byte) (sum & 0xff); |
| | | } |
| | | |
| | | //字符串转换为ascii |
| | | public static byte[] StrToAsc(String content) { |
| | | try { |
| | | return content.getBytes(StandardCharsets.US_ASCII); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | //ascii转换为string |
| | | public static String AscToStr(byte[] bytes) { |
| | | StringBuffer sbu = new StringBuffer(); |
| | | for (byte aByte : bytes) { |
| | | sbu.append(Character.toString((char) aByte)); |
| | | } |
| | | return sbu.toString(); |
| | | } |
| | | |
| | | public Class getClassType(String name){ |
| | | return null; |
| | | } |
| | |
| | | } |
| | | return mapping; |
| | | } |
| | | |
| | | public Map<String,String> toEncodeHexMapping() throws Exception{ |
| | | if(this.encodeBytes==null)this.encode(this); |
| | | if(this.encodeByteMapping==null)this.encodeByteMapping=new HashMap<>(); |
| | |
| | | mapping.put("byte[]", Struct.toHex(this.encodeBytes)); |
| | | return mapping; |
| | | } |
| | | |
| | | public Map<String,String> getHex(Map<String,byte[]> bytemapping) throws Exception { |
| | | Map<String,String> map = new LinkedHashMap<>(); |
| | | Field[] fields = this.getClass().getFields(); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | public byte[] convert(int size, long value) throws Exception{ |
| | | ByteArrayOutputStream baOs = new ByteArrayOutputStream(); |
| | | DataOutputStream dos = new DataOutputStream(baOs); |
| | |
| | | return (this.isReverse() ? Long.reverseBytes((long)value) : (long)value); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | @SuppressWarnings({ "unchecked", "rawtypes" }) |
| | | public static <T extends Struct> T decode(Class<? extends Struct> cls,byte[] bytes) throws Exception{ |
| | | Struct instance = cls.newInstance(); |
| | | return instance.decode(bytes); |
| | | } |
| | | |
| | | /** |
| | |
| | | return (T) instance; |
| | | } |
| | | |
| | | // 字节数组 ===>> 转为十六进制字符串 |
| | | public static String toHex(byte[] bytes) { |
| | | StringBuilder buf = new StringBuilder(bytes.length * 2); |
| | | for(byte b : bytes) { // 使用String的format方法进行转换 |
| | | buf.append(String.format("%02x", b & 0xff)); |
| | | } |
| | | return buf.toString().toUpperCase(); |
| | | } |
| | | public static byte[] toBytes(String str) { |
| | | if(str == null || str.trim().equals("")) return new byte[0]; |
| | | byte[] bytes = new byte[str.length() / 2]; |
| | | for(int i = 0; i < str.length() / 2; i++) { |
| | | String subStr = str.substring(i * 2, i * 2 + 2); |
| | | bytes[i] = (byte) Integer.parseInt(subStr, 16); |
| | | } |
| | | return bytes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * @功能: BCD码转为10进制串(阿拉伯数据) |
| | | * @参数: BCD码 |
| | | * @结果: 10进制串 |
| | | */ |
| | | public static String bcd2Str(byte[] bytes) { |
| | | StringBuffer temp = new StringBuffer(bytes.length * 2); |
| | | for (int i = 0; i < bytes.length; i++) { |
| | | temp.append((byte) ((bytes[i] & 0xf0) >>> 4)); |
| | | temp.append((byte) (bytes[i] & 0x0f)); |
| | | } |
| | | return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp |
| | | .toString().substring(1) : temp.toString(); |
| | | } |
| | | |
| | | /** |
| | | * @功能: 10进制串转为BCD码 |
| | | * @参数: 10进制串 |
| | | * @结果: BCD码 |
| | | */ |
| | | public static byte[] str2Bcd(String asc) { |
| | | int len = asc.length(); |
| | | int mod = len % 2; |
| | | if (mod != 0) { |
| | | asc = "0" + asc; |
| | | len = asc.length(); |
| | | } |
| | | byte abt[] = new byte[len]; |
| | | if (len >= 2) { |
| | | len = len / 2; |
| | | } |
| | | byte bbt[] = new byte[len]; |
| | | abt = asc.getBytes(); |
| | | int j, k; |
| | | for (int p = 0; p < asc.length() / 2; p++) { |
| | | if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) { |
| | | j = abt[2 * p] - '0'; |
| | | } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) { |
| | | j = abt[2 * p] - 'a' + 0x0a; |
| | | } else { |
| | | j = abt[2 * p] - 'A' + 0x0a; |
| | | } |
| | | if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) { |
| | | k = abt[2 * p + 1] - '0'; |
| | | } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) { |
| | | k = abt[2 * p + 1] - 'a' + 0x0a; |
| | | } else { |
| | | k = abt[2 * p + 1] - 'A' + 0x0a; |
| | | } |
| | | int a = (j << 4) + k; |
| | | byte b = (byte) a; |
| | | bbt[p] = b; |
| | | } |
| | | return bbt; |
| | | } |
| | | |
| | | public static class TestMessage { |
| | | public @size(1) byte begin = 0x7e;//起始符 |
| | | public @size(2) short type = 0;//消息ID |
| | |
| | | public @bit(1) byte subpkg;//消息体属性>是否分包,0表示不分包 |
| | | public @bit(3) byte encrypt;//消息体属性>加密方式,0表示不加密 |
| | | public @bit(10) short length;//消息体长度 |
| | | public @size(6) @flag("BCD") String number;//手机号码 |
| | | public @size(6) |
| | | @flag("BCD") String number;//手机号码 |
| | | public @size(2) short serial;//消息流水号 |
| | | public @expr("#subpkg==1?2:0") short pkgs;//分包数 |
| | | public @expr("#subpkg==1?2:0") short index;//包序号 |
| | | public @expr("#length") byte[] data;//数据部分 |
| | | public @size(1) byte verify;//校验码 |
| | | public @size(1) byte end = 0x7e;//结束符 |
| | | } |
| | | |
| | | public static byte getXor(byte[] datas,int start, int end){ |
| | | byte temp=datas[start]; |
| | | for (int i = start+1; i <end; i++) { |
| | | temp ^=datas[i]; |
| | | } |
| | | return temp; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 求校验和的算法 |
| | | * @param b 需要求校验和的字节数组 |
| | | * @return 校验和 |
| | | */ |
| | | public static byte sumCheck(byte[] b,int start, int end){ |
| | | int sum = 0; |
| | | for(int i = start; i < end; i++){ |
| | | sum = sum + b[i]; |
| | | } |
| | | return (byte) (sum & 0xff); |
| | | } |
| | | |
| | | //字符串转换为ascii |
| | | public static byte[] StrToAsc(String content){ |
| | | try { |
| | | return content.getBytes(StandardCharsets.US_ASCII); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | //ascii转换为string |
| | | public static String AscToStr(byte[] bytes){ |
| | | StringBuffer sbu = new StringBuffer(); |
| | | for (byte aByte : bytes) { |
| | | sbu.append(Character.toString((char) aByte)); |
| | | } |
| | | return sbu.toString(); |
| | | } |
| | | |
| | | } |