在解析一些二进制协议时,通常会使用到进制转换,这里提供一些整理的进制转换的工具类,相对来说还是比较全的。
10进制字节数组与16进制字节数组之间的转换
/**
* 10进制字节数组转换为16进制字节数组
*
* byte用二进制表示占用8位,16进制的每个字符需要用4位二进制位来表示,则可以把每个byte
* 转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16进制字符,再取对应16进制字符的字节
*
* @param b 10进制字节数组
* @return 16进制字节数组
*/
public static byte[] byte2hex(byte[] b) {
byte[] HEX_STRING_BYTE = HEX_CHAR.getBytes();
int length = b.length;
byte[] b2 = new byte[length << 1];
int pos;
for(int i=0; i<length; i++) {
pos = 2*i;
b2[pos] = HEX_STRING_BYTE[(b[i] & 0xf0) >> 4];
b2[pos+1] = HEX_STRING_BYTE[b[i] & 0x0f];
}
return b2;
}
/**
* 16进制字节数组转换为10进制字节数组
*
* 16进制数组格式为无空格, 如:6E7F8C
*
* 两个16进制字节对应一个10进制字节,则将第一个16进制字节对应成16进制字符表中的位置(0~15)并向左移动4位,
* 再与第二个16进制字节对应成16进制字符表中的位置(0~15)进行或运算,则得到对应的10进制字节
* @param b 16进制字节数组
* @return 10进制字节数组
*/
public static byte[] hex2byte(byte[] b) {
if(b.length%2 != 0) {
throw new IllegalArgumentException("byte array length is not even!");
}
int length = b.length >> 1;
byte[] b2 = new byte[length];
int pos;
for(int i=0; i<length; i++) {
pos = i << 1;
b2[i] = (byte) (HEX_CHAR.indexOf( b[pos] ) << 4 | HEX_CHAR.indexOf( b[pos+1] ) );
}
return b2;
}
16进制字节数组与字符串之间的转换
/**
* 将16进制字节数组转成10进制字符串
* @param b 16进制字节数组
* @return 10进制字符串
* 建议使用hexBytes2String
*/
public static String hex2Str(byte[] b) {
return new String(hex2byte(b));
}
/**
* 将10进制字节数组转成16进制字符串
* @param b 10进制字节数组
* @return 16进制字符串
*/
public static String byte2HexStr(byte[] b) {
return Integer.toHexString(Integer.parseInt(new String(b)));
}
/**
* 将16进制字节数组转成10进制字符串
* @param b 16进制字节数组
* @return 10进制字符串
*/
public static String hexBytes2String(byte[] b) {
String hexString = toHexString(b);
Long parseInt = Long.parseLong(hexString,16);
return String.valueOf(parseInt);
}
/**
* 将10进制字符串转成16进制字节数组
* @param string 10进制字符串
* @return 16进制字符串
*/
public static byte[] string2hexBytes(String string) {
String hexString = str2HexStr(string);
byte[] hexBytes = toByteArray(hexString.replaceAll(" ",""));
return hexBytes;
}
/**
* 16进制字符串转换成字节数组
*
* @param hex
* @return
*/
public static byte[] hexStringToByte(String hex) {
byte[] b = new byte[hex.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = hex.charAt(j++);
char c1 = hex.charAt(j++);
b[i] = (byte) ((parse(c0) << 4) | parse(c1));
}
return b;
}
private static int parse(char c) {
if (c >= 'a')
return (c - 'a' + 10) & 0x0f;
if (c >= 'A')
return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
}
16进制字符串与字节数组之间的转换
/**
* 字节数组转成16进制表示格式的字符串
* 字符串无空格
* @param byteArray
* 需要转换的字节数组
* @return 16进制表示格式的字符串
**/
public static String toHexString(byte[] byteArray) {
if (byteArray == null || byteArray.length < 1){
throw new IllegalArgumentException("this byteArray must not be null or empty");
}
final StringBuilder hexString = new StringBuilder();
for (int i = 0; i < byteArray.length; i++) {
if ((byteArray[i] & 0xff) < 0x10)// 0~F前面不零
hexString.append("0");
hexString.append(Integer.toHexString(0xFF & byteArray[i]));
}
return hexString.toString().toLowerCase();
}
/**
* 字符串表示转成16进制字节数组
*
* @param hexString
* 16进制格式的字符串
* @return 转换后的字节数组
**/
public static byte[] toByteArray(String hexString) {
if (StringUtils.isEmpty(hexString)){
throw new IllegalArgumentException("this hexString must not be empty");
}
hexString = hexString.toLowerCase();
final byte[] byteArray = new byte[hexString.length() / 2];
int k = 0;
// 因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
for (int i = 0; i < byteArray.length; i++) {
byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
byteArray[i] = (byte) (high << 4 | low);
k += 2;
}
return byteArray;
}
/**
* 字符串转换成十六进制字符串
*
* @param String str 待转换的ASCII字符串
* @return String 每个Byte之间空格分隔,如: [61 6C 6B]
*/
public static String str2HexStr(String str) {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
sb.append(' ');
}
return sb.toString().trim();
}
/**
* 十六进制转换字符串
*
* @param String str Byte字符串(Byte之间无分隔符 如:[616C6B])
* @return String 对应的字符串
*/
public static String hexStr2Str(String hexStr) {
String str = "0123456789ABCDEF";
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length() / 2];
int n;
for (int i = 0; i < bytes.length; i++) {
n = str.indexOf(hexs[2 * i]) * 16;
n += str.indexOf(hexs[2 * i + 1]);
bytes[i] = (byte) (n & 0xff);
}
return new String(bytes);
}
/**
* 将十六进制字符转换成一个整数
*
* @param ch 十六进制char
* @param index 十六进制字符在字符数组中的位置
* @return 一个整数
* @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
*/
protected static int toDigit(char ch, int index) {
int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new RuntimeException("Illegal hexadecimal character " + ch
+ " at index " + index);
}
return digit;
}
int转换为byte数组
/**
* 将int数值转换为占四个字节的byte数组 ,正序 ,低位在前,高位在后
* @param value 要转换的int值
* @return byte数组
*/
public static byte[] intToBytesLH(int value) {
byte[] src = new byte[4];
src[3] = (byte) ((value>>24) & 0xFF);
src[2] = (byte) ((value>>16) & 0xFF);
src[1] = (byte) ((value>>8) & 0xFF);
src[0] = (byte) (value & 0xFF);
return src;
}
/**
* 将byte数组转换为int数值,正序 ,低位在前,高位在后
* @param byte数组 ,起始位
* @return int
*/
public static int bytesToIntLH(byte[] src, int offset) {
int value;
value = (int) ((src[offset] & 0xFF)
| ((src[offset+1] & 0xFF)<<8)
| ((src[offset+2] & 0xFF)<<16)
| ((src[offset+3] & 0xFF)<<24));
return value;
}
/**
* 将int数值转换为占四个字节的byte数组 ,降序 ,高位在前,低位在后
@param value 要转换的int值
* @return byte数组
*/
public static byte[] intToBytes(int value) {
byte[] src = new byte[4];
src[0] = (byte) ((value>>24) & 0xFF);
src[1] = (byte) ((value>>16)& 0xFF);
src[2] = (byte) ((value>>8)&0xFF);
src[3] = (byte) (value & 0xFF);
return src;
}
/**
* 将byte数组转换为int数值,降序 ,高位在前,低位在后
* @param byte数组 ,起始位
* @return int
*/
public static int bytesToInt(byte[] src, int offset) {
int value;
value = (int) ( ((src[offset] & 0xFF)<<24)
|((src[offset+1] & 0xFF)<<16)
|((src[offset+2] & 0xFF)<<8)
|(src[offset+3] & 0xFF));
return value;
}
byte、short、int与字节数组之间的操作
/**
* 将int作为字节放入到字节数组中,占一个字节
* @param bdata 目标数组
* @param index 起始索引
* @param value 放入的值,
*/
public static void setByte(byte[] bdata, int index, int value) {
bdata[index] = ((byte) value);
}
/**
* 从字节数组中取对应的字节
* @param bdata 目标数组
* @param index 目标索引
* @return
*/
public static int getByte(byte[] bdata, int index) {
if (index < bdata.length - 1) {
return bdata[index] & 0xFF;
}
return 0;
}
/**
* 将int作为short放入到字节数组中,占两个字节
* @param bdata 目标数组
* @param index 起始索引
* @param value 放入的值,
*/
public static void setShort(byte[] bdata,int index, int value) {
bdata[index] = ((byte) (value >> 8 & 0xFF));
bdata[(index + 1)] = ((byte) (value & 0xFF));
}
/**
* 从字节数组中取对应的字节
* @param bdata 目标数组
* @param index 目标索引
* @return
*/
public static int getShort(byte[] bdata, int index) {
if (index < bdata.length - 2) {
return (getByte(bdata, index) << 8) + getByte(bdata, index + 1);
}
return 0;
}
/**
* byte数组中取int数值,正序,低位在前,高位在后
* @param ary byte数组
* @param offset 从数组的第offset位开始
* @return int数值
*/
public static int getIntOnBytesLH(byte[] ary, int offset) {
int value;
value = (int) ((ary[offset]&0xFF)
| ((ary[offset+1]<<8) & 0xFF00)
| ((ary[offset+2]<<16)& 0xFF0000)
| ((ary[offset+3]<<24) & 0xFF000000));
return value;
}
/**
* byte数组中取int数值,正序,高位在前,低位在后
* @param ary byte数组
* @param offset 从数组的第offset位开始
* @return int数值
*/
public static int getIntOnBytes(byte[] ary, int offset) {
int value;
value = (int) (((ary[offset] << 24) & 0xFF000000)
| ((ary[offset + 1] << 16) & 0xFF0000)
| ((ary[offset + 2] << 8) & 0xFF00) | (ary[offset + 3] & 0xFF));
return value;
}
public static void setIntOnBytes(byte[] ary, int offset,int value){
byte[] bytes = intToBytes(value);
addBytes(ary, offset, bytes);
}
public static int getIntFromBytes(byte high_h, byte high_l, byte low_h, byte low_l) {
return (high_h & 0xff) << 24 | (high_l & 0xff) << 16 | (low_h & 0xff) << 8 | low_l & 0xff;
}
上面的分类可能不是特别详细,按照自己的需求,选择需要的函数