1.接收16进制报文,去空格转大写,使用byte[ ]接收(注:java默认显示十进制)
2.将byte[ ]转String的16进制数
3.CRC16Modbus校验
4.生成CRC16Modbus校验码
5.将byte16进制数转float
6.将一个高字节和低字节16进制数转10进制
7.16进制转ASCII码
/**
* String 转 byte[]
*
* @param hexString
* @return
*/
public static byte[] hexStringToByte(String hexString) {
if (hexString == null || StringUtil.isNullOrEmpty(hexString)) {
return null;
}
//转大写,去空格
hexString = hexString.toUpperCase().replace(" ", "");
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* byte[]转String
* @param hexByte
* @return
*/
public static String hexByteToString(byte[] hexByte){
if(hexByte == null){
return null;
}
StringBuilder hex = new StringBuilder();
for (byte b : hexByte) {
hex.append(HEXES[(b >> 4) & 0x0F]);
hex.append(HEXES[b & 0x0F]);
}
return hex.toString();
}
private static final char[] HEXES = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'
};
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
/**
* 生成CRC16-Modbus校验码并返回校验是否成功
* @param
* @return
*/
public static boolean getCRC16Modbus(byte[] bytes){
int CRC = 0x0000FFFF;
int POLYNOMIAL = 0x0000A001;
//长度-2,去除校验为
int i, j;
for (i = 0; i < bytes.length-2 ; i++) {
CRC ^= ((int) bytes[i] & 0x000000ff);
for (j = 0; j < 8; j++) {
if ((CRC & 0x00000001) != 0) {
CRC >>= 1;
CRC ^= POLYNOMIAL;
} else {
CRC >>= 1;
}
}
}
//假如校验相反则取消注释
// CRC = ((CRC & 0x0000FF00) >> 8) | ((CRC & 0x000000FF) << 8);
String crc1 = String.format("%04X",CRC);
String crc2 = String.format("%02X",bytes[bytes.length-1])+String.format("%02X",bytes[bytes.length-2]);
log.info("源码:"+crc1+"---系统:"+crc2);
if(crc1.equals(crc2)){
return true;
}
return false;
}
/**
* 在原有的byte上生成校验
* @param bytes
* @return
*/
public static byte[] setCRC16Modbus(byte[] bytes){
int CRC = 0x0000FFFF;
int POLYNOMIAL = 0x0000A001;
byte[] bt = new byte[2];
//长度-2,去除校验为
int i, j;
for (i = 0; i < bytes.length-2 ; i++) {
CRC ^= ((int) bytes[i] & 0x000000ff);
for (j = 0; j < 8; j++) {
if ((CRC & 0x00000001) != 0) {
CRC >>= 1;
CRC ^= POLYNOMIAL;
} else {
CRC >>= 1;
}
}
}
CRC = ((CRC & 0x0000FF00) >> 8) | ((CRC & 0x000000FF) << 8);
bt = hexStringToByte(String.format("%04X",CRC));
bytes[bytes.length-2]=bt[0];
bytes[bytes.length-1]=bt[1];
return bytes;
}
/**
* 计算数值
* @param b 原数组
* @param index,开始标志位
* @return 返回float型数据
*/
public static float byteToFloat(byte[] b, int index) {
int l;
l = b[index + 3];
l &= 0xff;
l |= ((long) b[index + 2] << 8);
l &= 0xffff;
l |= ((long) b[index + 1] << 16);
l &= 0xffffff;
l |= ((long) b[index + 0] << 24);
return Float.intBitsToFloat(l);
}
/**
* 两位byte转int
* @param bt1 0
* @param bt2 1
* @return int
*/
public static int byteGetInt(byte bt1,byte bt2){
return (bt1 & 0xff) << 8 | (bt2 & 0xff);
}
16进制转ASCII码
byte[] bt = new []{97,98,99,100};
String dx = new String(bt ,"ascii"); //abcd
码后点心:
byte[]截取指定长度
byte[] bt1 = new byte[]{1,2,3,4,5,6,7,8};
byte[] bt2 = new byte[4];
//参数2 标志位 ,参数5 长度
System.arraycopy(bt1 , 0, bt2, 0, 4); //1234
System.arraycopy(bt1 , 1, bt2, 0, 4); //2345
单个byte转16进制String
byte bt = 10;
String.format("%04X", byte); //保留高位和低位,000A
String.format("%02X", byte); //保留两位,0A