碰到问题是终端设备直接上报数据为 base64 加密的。
首先先把数据解析成16进制字符串。
然后按照协议进行位数截取可以得到对应的属性
这里拿比如截取后的属性是温度,十六进制字符串是 1D01
那个硬件师傅说这个数据其实是小端数据。
而java 是大端数据,那么就要进行数据的调换位置,就变成了011D
011D是16进制,需要转成10进制
就是285,协议里又说 这个数组要除以10,那么最终协议解析出来这个设备的温度字段值就是28.5
当然整个解决流程都是因为文档哈,不同的文档,肯定意思不同,但是大同小异,稍做调整,因为没问题
总结:还是仔细看文档,不理解及时沟通,不懂的方面很多,需要跟别人取经。
下面给出几个转换的方法
/**
* 解析数据方法
*/
private static final char[] DIGITS
= {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static final String toHex(byte[] data) {
final StringBuffer sb = new StringBuffer(data.length * 2);
for (int i = 0; i < data.length; i++) {
sb.append(DIGITS[(data[i] >>> 4) & 0x0F]);
sb.append(DIGITS[data[i] & 0x0F]);
}
return sb.toString();
}
/**
* 小端转大端
*
* @param str
* @return
*/
public static byte[] string2Bytes(String str) {
if (str == null || str.equals("")) {
return null;
}
str = str.toUpperCase();
int length = str.length() / 2;
char[] strChar = str.toCharArray();
byte[] bt = new byte[length];
for (int i = 0; i < length; i++) {
int index = i * 2;
bt[i] = (byte) (char2Byte(strChar[index]) << 4 | char2Byte(strChar[index + 1]));
}
return bt;
}
private static byte char2Byte(char ch) {
return (byte) "0123456789ABCDEF".indexOf(ch);
}
public final static long getLong(byte[] bt, boolean isAsc) {
//BIG_ENDIAN
if (bt == null) {
throw new IllegalArgumentException("byte array is null.");
}
if (bt.length > 8) {
throw new IllegalArgumentException("byte array size more than 8.");
}
long result = 0;
if (isAsc) {
for (int i = bt.length - 1; i >= 0; i--) {
result <<= 8;
result |= (bt[i] & 0x00000000000000ff);
}
} else {
for (int i = 0; i < bt.length; i++) {
result <<= 8;
result |= (bt[i] & 0x00000000000000ff);
}
}
return result;
}
/**
* 16进制转10进制
* 对方协议 大小写都是大写
*
* @param
* @return
*/
public static int hexToDecimal(String hex) {
int outcome = 0;
for (int i = 0; i < hex.length(); i++) {
char hexChar = hex.charAt(i);
outcome = outcome * 16 + charToDecimal(hexChar);
}
return outcome;
}
public static int charToDecimal(char c) {
if (c >= 'A' && c <= 'F'){
return 10 + c - 'A';
} else{
return c - '0';
}
}
/**
* 测试
*/
public static void main(String[] args) {
String temp = "1D01";
byte[] tempBytes = string2Bytes(temp);
String tempRecord = Long.toHexString(getLong(tempBytes, true));
tempRecord = tempRecord.toUpperCase();
int tempCovert = hexToDecimal(tempRecord);
Double tempDouble = Double.valueOf(tempCovert) / 10;
System.out.println(tempDouble);
}