杰瑞科技汇

byte数组转16进制,Java如何实现?

为什么需要转换?

byte 数组在 Java 中通常用于处理二进制数据,如文件内容、网络数据包、加密后的数据等,而 16 进制字符串是一种人类可读的格式,常用于:

byte数组转16进制,Java如何实现?-图1
(图片来源网络,侵删)
  • 日志记录和调试
  • 显示哈希值(如 MD5, SHA-256)
  • 网络协议数据交换
  • 配置文件中存储二进制数据

使用 javax.xml.bind.DatatypeConverter (JDK 1.7 及以下推荐)

这是在 Java 8 之前非常流行和方便的方法,因为它属于标准库的一部分,无需引入第三方依赖。

优点

  • 简单直接:API 非常简洁。
  • 无需依赖:是 Java 标准库的一部分。

缺点

  • 已过时:自 Java 9 起,javax.xml.bind 包被标记为过时,并在 Java 11 中被完全移除,如果你使用的是新版本的 JDK,编译器会给出警告。
  • 包名冗长:需要写一长串包名。

代码示例

import javax.xml.bind.DatatypeConverter;
public class ByteArrayToHexConverter {
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0xFF, (byte) 0xA0, (byte) 0x01, (byte) 0x2B };
        // 使用 DatatypeConverter 将 byte 数组转换为 16 进制字符串
        String hexString = DatatypeConverter.printHexBinary(bytes);
        System.out.println("转换后的 16 进制字符串: " + hexString);
        // 输出: 转换后的 16 进制字符串: FFA0012B
    }
}

使用 java.util.Base64 (JDK 8+ 推荐,但用于 Base64)

从 Java 8 开始,引入了 java.util.Base64 类,但它主要用于 Base64 编解码,虽然它不直接提供 16 进制转换,但了解它是好的。

注意:这个方法不适用于byte 数组转换为 16 进制字符串,这里提及它只是为了澄清一个常见的误解,请使用下面的 Hex 类。


使用 Apache Commons Codec (最灵活、最推荐)

这是目前最常用、最灵活且社区支持最好的方法,它提供了一个专门的 Hex 工具类。

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

优点

  • API 优秀:设计简洁,易于使用。
  • 性能高:经过高度优化。
  • 功能全面:不仅支持编码,还支持解码。
  • 社区活跃:广泛使用,稳定可靠。

缺点

  • 需要引入依赖:需要添加 Apache Commons Codec 的库到你的项目中。

如何添加依赖

Maven (pom.xml):

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

Gradle (build.gradle):

implementation 'commons-codec:commons-codec:1.15' // 建议使用最新版本

代码示例

import org.apache.commons.codec.binary.Hex;
public class ByteArrayToHexConverter {
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0xFF, (byte) 0xA0, (byte) 0x01, (byte) 0x2B };
        // 使用 Hex.encodeHexString() 方法
        String hexString = Hex.encodeHexString(bytes);
        System.out.println("转换后的 16 进制字符串: " + hexString);
        // 输出: 转换后的 16 进制字符串: ffa0012b
        // 如果需要大写字母
        String upperHexString = Hex.encodeHexString(bytes).toUpperCase();
        System.out.println("大写 16 进制字符串: " + upperHexString);
        // 输出: 大写 16 进制字符串: FFA0012B
        // 解码示例
        byte[] decodedBytes = Hex.decodeHexString(hexString);
        System.out.println("解码后的 byte 数组长度: " + decodedBytes.length);
    }
}

手动实现 (不推荐,但有助于理解原理)

在某些极端情况下(如不能使用任何外部库),你可能需要自己实现转换逻辑。

优点

  • 无任何依赖:纯 Java 实现。
  • 有助于学习:能让你理解底层转换过程。

缺点

  • 代码冗长:需要自己处理循环、格式化和异常。
  • 容易出错:需要正确处理负数 byte 和补零。
  • 性能较差:通常没有优化过的库性能高。

代码示例

public class ByteArrayToHexConverter {
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0xFF, (byte) 0xA0, (byte) 0x01, (byte) 0x2B };
        String hexString = bytesToHex(bytes);
        System.out.println("手动转换后的 16 进制字符串: " + hexString);
        // 输出: 手动转换后的 16 进制字符串: FFA0012B
    }
    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++) {
            // 将 byte 转换为无符号的 int 值 (0-255)
            int v = bytes[i] & 0xFF;
            // 取高 4 位
            hexChars[i * 2] = HEX_ARRAY[v >>> 4];
            // 取低 4 位
            hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }
}

关键点bytes[i] & 0xFF 是最关键的一步,Java 的 byte 是有符号的(范围是 -128 到 127),通过与 0xFF(二进制 11111111)进行位与操作,可以将其转换为 0 到 255 之间的无符号整数,这样才能正确映射到 16 进制字符。

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

总结与选择建议

方法 优点 缺点 推荐场景
javax.xml.bind.DatatypeConverter 简单,无依赖 已过时,JDK 11+ 需额外配置 不推荐,仅用于维护旧项目(JDK 8-)
Apache Commons Codec API优秀,性能高,功能全 需要引入外部依赖 强烈推荐,新项目首选
手动实现 无依赖,有助于学习 代码冗长,易出错,性能低 学习目的,或项目有严格的依赖限制
java.util.Base64 标准库,无依赖 用于 Base64,不用于 16 进制 需要编码 Base64 时使用

最终建议:

  • 对于所有新项目,请优先使用 Apache Commons Codec,它的稳定性和易用性是最好的。
  • 如果你正在维护一个旧项目,并且使用的是 JDK 8 或更早版本javax.xml.bind.DatatypeConverter 是一个可接受的快速解决方案。
  • 尽量避免手动实现,除非你完全理解其原理并且有特殊要求。
分享:
扫描分享到社交APP
上一篇
下一篇