You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中使用Scanner将十六进制字符串转为字节数组失败求助

问题原因分析

你遇到的核心问题是Scanner的hasNextByte(16)方法不会自动识别十六进制的0x前缀。

Scanner默认以空白字符作为分隔符,当输入是0xAA 0xBB这类格式时,每个独立的token是0xAA——这个字符串包含了非十六进制有效字符x,导致hasNextByte(16)判定它无法被解析为十六进制byte,循环根本不会执行,最终自然返回空数组。

哪怕输入是不带前缀的AA BB CC,如果后续有带前缀的混合输入,同样会触发这个问题,所以得针对性处理前缀问题。

解决方案

针对带0x前缀和不带前缀的两种输入格式,这里提供两种实用的处理方式:

方式一:预处理输入字符串,移除0x前缀

先把输入中的所有0x(或0X)前缀清除,让Scanner直接解析纯十六进制字符:

byte[] bytesFromString(String value) {
    // 移除所有大小写的0x前缀,不区分大小写
    String cleanedInput = value.replaceAll("(?i)0x", "");
    List<Byte> byteList = new ArrayList<>();
    Scanner scanner = new Scanner(cleanedInput);
    
    while (scanner.hasNextByte(16)) {
        byteList.add(scanner.nextByte(16));
    }
    
    // 转换为byte数组
    byte[] result = new byte[byteList.size()];
    for (int i = 0; i < byteList.size(); i++) {
        result[i] = byteList.get(i);
    }
    return result;
}

方式二:手动处理每个Token,兼容两种格式

如果需要同时兼容带前缀和不带前缀的输入,可以逐个读取token,判断并移除前缀后再解析,还能顺便处理无效输入:

byte[] bytesFromString(String value) {
    List<Byte> byteList = new ArrayList<>();
    Scanner scanner = new Scanner(value);
    
    while (scanner.hasNext()) {
        String token = scanner.next();
        String hexStr = token;
        
        // 处理带0x/0X前缀的情况
        if (token.startsWith("0x") || token.startsWith("0X")) {
            hexStr = token.substring(2);
        }
        
        try {
            // 用十六进制基数解析为byte
            byte b = Byte.parseByte(hexStr, 16);
            byteList.add(b);
        } catch (NumberFormatException e) {
            // 可选:处理无效的十六进制字符串,比如跳过或抛出自定义异常
            System.err.println("无效的十六进制值:" + token);
        }
    }
    
    // 转换为byte数组
    byte[] result = new byte[byteList.size()];
    for (int i = 0; i < byteList.size(); i++) {
        result[i] = byteList.get(i);
    }
    return result;
}
额外注意事项
  • byte的范围限制:Java中byte的取值范围是-128到127,如果输入的十六进制值超过这个范围(比如0xFF,对应十进制255),Byte.parseByte会抛出NumberFormatException。如果需要处理无符号byte,可以先解析为int再强转为byte,例如(byte) Integer.parseInt(hexStr, 16)。
  • 大小写兼容:上述代码已经兼容大小写的0X前缀和十六进制字符(比如aA也是有效的),因为Byte.parseByte和Scanner的hasNextByte(16)都不区分大小写。

内容的提问来源于stack exchange,提问作者yageek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:16:34