杰瑞科技汇

Java 16进制String如何转byte数组?

将字节数组(byte[])转换为 16 进制字符串

这是最常见的操作之一,例如将哈希值、加密结果等字节数据以可读的字符串形式表示。

Java 16进制String如何转byte数组?-图1
(图片来源网络,侵删)

使用 javax.xml.bind.DatatypeConverter (JDK 1.6+)

这是最简单直接的方法,但需要注意它属于 javax.xml.bind 包,在 Java 9+ 中已被标记为 deprecated,且在 Java 11+ 中默认不可用(需要添加 --add-modules java.xml.bind 参数)。

import javax.xml.bind.DatatypeConverter;
public class HexUtil {
    public static String bytesToHex(byte[] bytes) {
        return DatatypeConverter.printHexBinary(bytes);
    }
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0xFF, 0x00, 0x7A, (byte) 0xCD };
        String hexString = bytesToHex(bytes);
        System.out.println(hexString); // 输出: FF007ACD
    }
}

使用 Apache Commons Codec (推荐)

这是最常用和推荐的方法,因为它稳定、易用,且不依赖于 Java 内部可能被移除的 API。

需要在你的项目中添加依赖(Maven):

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version> <!-- 使用最新版本 -->
</dependency>

然后使用 Hex 工具类:

Java 16进制String如何转byte数组?-图2
(图片来源网络,侵删)
import org.apache.commons.codec.binary.Hex;
public class HexUtil {
    public static String bytesToHex(byte[] bytes) {
        return Hex.encodeHexString(bytes);
    }
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0xFF, 0x00, 0x7A, (byte) 0xCD };
        String hexString = bytesToHex(bytes);
        System.out.println(hexString); // 输出: ff007acd (默认小写)
        // 如果需要大写
        System.out.println(hexString.toUpperCase()); // 输出: FF007ACD
    }
}

手动实现(不依赖任何库)

如果你不想引入外部依赖,可以手动实现一个转换函数,原理很简单:遍历字节数组的每一个字节,将其转换为两个 16 进制字符。

public class HexUtil {
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        char[] hexChars = new char[bytes.length * 2];
        for (int i = 0; i < bytes.length; i++) {
            int v = bytes[i] & 0xFF; // 将字节转换为无符号整型 (0-255)
            hexChars[i * 2] = HEX_ARRAY[v >>> 4]; // 取高4位
            hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F]; // 取低4位
        }
        return new String(hexChars);
    }
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0xFF, 0x00, 0x7A, (byte) 0xCD };
        String hexString = bytesToHex(bytes);
        System.out.println(hexString); // 输出: FF007ACD
    }
}

将 16 进制字符串转换为字节数组(byte[])

这是上述操作的逆过程,例如将从网络接收或从文件读取的 16 进制字符串还原为原始数据。

使用 javax.xml.bind.DatatypeConverter

import javax.xml.bind.DatatypeConverter;
public class HexUtil {
    public static byte[] hexToBytes(String hexString) {
        return DatatypeConverter.parseHexBinary(hexString);
    }
    public static void main(String[] args) {
        String hexString = "FF007ACD";
        byte[] bytes = hexToBytes(hexString);
        // 打印字节数组内容
        for (byte b : bytes) {
            System.out.printf("%02X ", b); // 输出: FF 00 7A CD
        }
    }
}

使用 Apache Commons Codec

import org.apache.commons.codec.binary.Hex;
public class HexUtil {
    public static byte[] hexToBytes(String hexString) {
        return Hex.decodeHex(hexString.toCharArray());
    }
    public static void main(String[] args) {
        String hexString = "FF007ACD";
        byte[] bytes = hexToBytes(hexString);
        // ...
    }
}

手动实现

public class HexUtil {
    public static byte[] hexToBytes(String hexString) {
        if (hexString == null || hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("Invalid hex string");
        }
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                                 + Character.digit(hexString.charAt(i+1), 16));
        }
        return data;
    }
    public static void main(String[] args) {
        String hexString = "FF007ACD";
        byte[] bytes = hexToBytes(hexString);
        // ...
    }
}

从 16 进制字符串中提取单个字节

如果你有一个长的 16 进制字符串,并想获取其中某个位置的字节,可以先将其转换为 byte[],然后通过索引访问。

public class HexUtil {
    public static byte getByteFromHexString(String hexString, int index) {
        if (index < 0 || index * 2 >= hexString.length()) {
            throw new IndexOutOfBoundsException("Invalid index for hex string");
        }
        // 提取代表该字节的两个字符
        String byteHex = hexString.substring(index * 2, index * 2 + 2);
        return (byte) Integer.parseInt(byteHex, 16);
    }
    public static void main(String[] args) {
        String longHexString = "A1B2C3D4E5F6";
        // 获取第二个字节 (索引为1)
        byte secondByte = getByteFromHexString(longHexString, 1);
        System.out.printf("The second byte is: 0x%02X\n", secondByte); // 输出: 0xB2
    }
}

在 Java 17 中使用 Integer.toHexString()Integer.parseInt()

对于单个整数的转换,可以使用 Integer 类的内置方法。

整数转 16 进制字符串

int number = 255;
String hexString = Integer.toHexString(number);
System.out.println(hexString); // 输出: ff (小写)
// 如果需要固定宽度和前缀
String formattedHex = String.format("0x%08X", number);
System.out.println(formattedHex); // 输出: 0x000000FF

16 进制字符串转整数

String hexString = "FF";
int number = Integer.parseInt(hexString, 16);
System.out.println(number); // 输出: 255
// 如果字符串有 "0x" 前缀,parseInt 无法直接处理
String hexWithPrefix = "0xFF";
// number = Integer.parseInt(hexWithPrefix, 16); // 会抛出 NumberFormatException
// 正确做法是去掉前缀
number = Integer.parseInt(hexWithPrefix.substring(2), 16);
System.out.println(number); // 输出: 255

总结与最佳实践

操作场景 推荐方法 备注
字节数组 ↔ 16进制字符串 Apache Commons Codec 最推荐,稳定、简洁、无依赖问题。
手动实现 适用于不能引入外部库的环境。
javax.xml.bind.DatatypeConverter 不推荐,未来可能被移除。
单个整数 ↔ 16进制字符串 Integer.parseInt() / Integer.toHexString() Java 内置方法,无需额外库。
处理带前缀的字符串 String.substring() 在使用 parseInt 前,手动去除 "0x" 或 "0X" 前缀。

对于任何与字节数据相关的 16 进制转换,强烈建议使用 Apache Commons Codec 库,它经过了充分测试,能正确处理各种边界情况,并且代码非常清晰易读。

分享:
扫描分享到社交APP
上一篇
下一篇