简介
原理
由于十六进制的最大值为15(F),其二进制形式为1111,占4bit
,一个字节(byte
)为8bit
,故一个字节可用于表示两个十六进制字符,即一个长度为n的字节数组可存储长度为2n或2n - 1的十六进制字符串
顺序
字节数组分为大字节序和小字节序,大字节序高位在前,低位在后,小字节序反之
实现
char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
static byte[] hexToBytes(String hex, boolean bigEndian) {
hex = preHandHex(hex);
if (!hex.matches("^[\\dA-F]+$")) {
throw new IllegalArgumentException(hex + " 不是十六进制格式");
}
byte[] bytes = new byte[hex.length() % 2 == 0 ? hex.length() / 2 : hex.length() / 2 + 1];
for (int i = hex.length() - 1; i >= 0; i -= 2) {
//后位数
int hinderValue = getValue(hex.charAt(i));
//前位数,没有则为0
int aheadValue = i - 1 < 0 ? 0x0 : getValue(hex.charAt(i - 1));
if (bigEndian) {
bytes[i / 2] = (byte) (aheadValue << 4 | hinderValue);
} else {
//倒序写入
bytes[bytes.length - 1 - i / 2] = (byte) (hinderValue << 4 | aheadValue);
}
}
return bytes;
}
static String bytesToHex(byte[] bytes, boolean bigEndian) {
StringBuilder builder = new StringBuilder();
for (byte b : bytes) {
//前位数
builder.append(HEX_CHARS[(b & 0xF0) >> 4]);
//后位数
builder.append(HEX_CHARS[b & 0x0F]);
}
return removeZero(bigEndian ? builder.toString() : builder.reverse().toString());
}
private static int getValue(char c) {
for (int i = 0; i < HEX_CHARS.length; i++) {
if (HEX_CHARS[i] == c) {
return i;
}
}
throw new IllegalArgumentException();
}
/**
* 去除0
* @param hex
* @return
*/
private static String removeZero(String hex) {
return hex.replaceAll("^0+", "");
}
/**
* 预处理
* @param hex
* @return
*/
private static String preHandHex(String hex) {
return removeZero(hex.trim().toUpperCase());
}