首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 字符串與 byte 數組互轉核心原理與高性能實現

     編輯:Java 相關知識

核心原理:位運算與十六進制映射

1 byte = 8 位 = 2 個十六進制字符 (4 位/字符)

byte 值:123 (0x7B)
二進制:0111 1011
高 4 位:0111 (7) → 字符 '7'
低 4 位:1011 (B) → 字符 'B'
結果:"7B"

方案一:查表法 (最高性能,推薦)

public class HexUtil {
    private static final char[] HEX_DIGITS = 
        {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

    /** byte[] → 十六進制字符串 */
    public static String bytesToHex(byte[] src) {
        if (src == null || src.length == 0) return "";
        char[] res = new char[src.length * 2];
        for (int i = 0, j = 0; i < src.length; i++) {
            res[j++] = HEX_DIGITS[(src[i] >>> 4) & 0x0F]; // 高 4 位 (無符號右移)
            res[j++] = HEX_DIGITS[src[i] & 0x0F];         // 低 4 位
        }
        return new String(res);
    }

    /** 十六進制字符串 → byte[] */
    public static byte[] hexToBytes(String hex) {
        if (hex == null || hex.isEmpty() || (hex.length() & 1) != 0) return null;
        byte[] bytes = new byte[hex.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            int high = Character.digit(hex.charAt(i * 2), 16);
            int low = Character.digit(hex.charAt(i * 2 + 1), 16);
            if (high == -1 || low == -1) return null; // 非法字符
            bytes[i] = (byte) ((high << 4) | low);
        }
        return bytes;
    }
}

方案二:BigInteger / String.format (簡潔但較慢)

// byte[] → Hex
public static String toHexBigInteger(byte[] bytes) {
    return new BigInteger(1, bytes).toString(16); // 注意:會丟失前導零
}

// Hex → byte[]
public static byte[] fromHexBigInteger(String hex) {
    return new BigInteger(hex, 16).toByteArray(); // 可能產生額外符號位
}

方案三:Java 17+ HexFormat (標準庫,推薦新項目)

import java.util.HexFormat;

public class ModernHexUtil {
    private static final HexFormat FORMAT = HexFormat.of().withUpperCase();

    public static String toHex(byte[] bytes) {
        return FORMAT.formatHex(bytes);
    }

    public static byte[] fromHex(String hex) {
        return FORMAT.parseHex(hex);
    }
}

實戰應用:文件 MD5 校驗

public static String getFileMD5(File file) throws IOException {
    try (FileInputStream fis = new FileInputStream(file);
         DigestInputStream dis = new DigestInputStream(fis, MessageDigest.getInstance("MD5"))) {
        
        // 必須讀完流才能觸發摘要計算
        byte[] buffer = new byte[8192];
        while (dis.read(buffer) != -1) { /* 讀取觸發更新 */ }
        
        return HexUtil.bytesToHex(dis.getMessageDigest().digest());
    } catch (NoSuchAlgorithmException e) {
        throw new IllegalStateException("MD5 算法不可用", e);
    }
}

性能基準參考 (百萬次調用)

方法耗時 (ms)相對性能
查表法 (方案一)~1201.0x (基準)
HexFormat (Java 17+)~1501.25x
String.format("%02x")~8507x
BigInteger~210017x

常見坑點避坑指南

  • byte 符號擴展:byte b = -1; b & 0xFF 得到 255,必須配合 & 0xFF 消除符號位
  • 前導零丟失:new BigInteger(1, bytes).toString(16) 會丟失高位零,需手動補齊
  • 大小寫一致性:解析時不區分大小寫,生成時統一規範 (推薦小寫)
  • 奇數長度字符串:非法輸入,需預檢 hex.length() % 2 == 0

總結

字符串與 byte[] 互轉本質是二進制與十六進制文本表示的轉換。生產環境推薦:Java 17+ 使用 HexFormat,舊版本使用查表法 (方案一),兼顧性能與零依賴。避免使用 String.format/BigInteger 等高開銷方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved