这是将字符串hex转换为字节的最佳方法吗?

这是将字符串hex转换为字节的最佳方法吗? 或者你能想得更短/更简单吗?

public static byte[] hexToBytes(String hex) { return hexToBytes(hex.toCharArray()); } public static byte[] hexToBytes(char[] hex) { int length = hex.length / 2; byte[] raw = new byte[length]; for (int i = 0; i < length; i++) { int high = Character.digit(hex[i * 2], 16); int low = Character.digit(hex[i * 2 + 1], 16); int value = (high < 127) value -= 256; raw[i] = (byte) value; } return raw; } 

 byte[] yourBytes = new BigInteger(hexString, 16).toByteArray(); 

当值大于127时,您不需要减去256.只需将值转换为一个字节。 例如, byte b = (byte) 255将值-1赋给b

对整数类型进行缩小转换只会丢弃不适合目标类型的高阶位。

  private static byte[] hexToBytes(char[] hex) { byte[] raw = new byte[hex.length / 2]; for (int src = 0, dst = 0; dst < raw.length; ++dst) { int hi = Character.digit(hex[src++], 16); int lo = Character.digit(hex[src++], 16); if ((hi < 0) || (lo < 0)) throw new IllegalArgumentException(); raw[dst] = (byte) (hi << 4 | lo); } return raw; } 

不幸的是,当前导零字节时,使用BigInteger失败。

我认为你原来的方法是一个好的开始。 我做了一些调整:

 @NotNull public static byte[] hexToBytes(@NotNull String hex) { return hexToBytes(hex.toCharArray()); } @NotNull public static byte[] hexToBytes(@NotNull char[] hex) { if (hex.length % 2 != 0) throw new IllegalArgumentException("Must pass an even number of characters."); int length = hex.length >> 1; byte[] raw = new byte[length]; for (int o = 0, i = 0; o < length; o++) { raw[o] = (byte) ((getHexCharValue(hex[i++]) << 4) | getHexCharValue(hex[i++])); } return raw; } public static byte getHexCharValue(char c) { if (c >= '0' && c <= '9') return (byte) (c - '0'); if (c >= 'A' && c <= 'F') return (byte) (10 + c - 'A'); if (c >= 'a' && c <= 'f') return (byte) (10 + c - 'a'); throw new IllegalArgumentException("Invalid hex character"); } 

请注意, Character.digit仅在Java 7中可用,并且它不validation提供的字符是否在预期范围内。 当输入数据与我的期望不符时,我喜欢抛出exception,所以我添加了。

以下是一些基本的unit testing:

 @Test public void hexToBytes() { assertArrayEquals(new byte[]{0x00, 0x01, 0x02}, Convert.hexToBytes("000102")); assertArrayEquals(new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0xFD}, Convert.hexToBytes("FFFEFD")); assertArrayEquals(new byte[]{(byte) 0xFF}, Convert.hexToBytes("FF")); assertArrayEquals(new byte[]{(byte) 0x00}, Convert.hexToBytes("00")); assertArrayEquals(new byte[]{(byte) 0x01}, Convert.hexToBytes("01")); assertArrayEquals(new byte[]{(byte) 0x7F}, Convert.hexToBytes("7F")); assertArrayEquals(new byte[]{(byte) 0x80}, Convert.hexToBytes("80")); } @Test(expected = IllegalArgumentException.class) public void hexToBytesThrowsIfOddNumberOfCharacters() { Convert.hexToBytes("12345"); // Odd number of characters } @Test(expected = IllegalArgumentException.class) public void hexToBytesThrowsIfInvalidCharacters() { Convert.hexToBytes("ABCDEFGH"); // G and H are invalid in base 16 } @Test public void getHexCharValue() { assertEquals(0x0, Convert.getHexCharValue('0')); assertEquals(0x1, Convert.getHexCharValue('1')); assertEquals(0x9, Convert.getHexCharValue('9')); assertEquals(0xa, Convert.getHexCharValue('A')); assertEquals(0xf, Convert.getHexCharValue('F')); assertEquals(0xa, Convert.getHexCharValue('a')); assertEquals(0xf, Convert.getHexCharValue('f')); } @Test(expected = IllegalArgumentException.class) public void getHexCharValueThrowsIfInvalid1() { Convert.getHexCharValue('z'); } 

最简单的方法:

 private static byte[] hexToBytes(char[] hex) { return DatatypeConverter.parseHexBinary(hex.toString()); }