Java中读取十六进制密钥并转换为byte[]数组的问题求助
嘿,我明白你遇到的问题了——Java的Byte.parseByte()是处理有符号字节的(范围-128到127),而像89这样的十六进制值对应的十进制是137,超出了有符号byte的上限,直接用二进制字符串解析就会抛出NumberFormatException。更别说如果你的hexToBinary方法还出了小差错(比如报错里的"100011"明显不是89对应的完整二进制),问题会更麻烦。
给你几个直接可靠的解决方案,不用绕二进制字符串的弯路:
方法一:直接转int再强转byte(推荐,无依赖)
每个两位的十六进制字符串(比如"89")可以先转成int(范围足够覆盖0-255),再强转成byte。Java会自动处理补码转换,超过127的数值会变成对应的负数,但这完全不影响加密算法对字节二进制位的使用——因为加密只关心8位二进制的实际内容,不管它是正还是负。
代码示例:
// 假设你已经把文件内容分割成了hex数组,比如["01", "23", "45", ..., "EF"] byte[] requiredByte = new byte[hex.length]; for (int i = 0; i < hex.length; i++) { // 先解析为16进制int,再强转成byte int hexValue = Integer.parseInt(hex[i], 16); requiredByte[i] = (byte) hexValue; }
比如"89"转成int是137,强转成byte后会变成-119,它的二进制是10001001,和原十六进制的二进制完全一致,这正是你需要的结果。
方法二:使用Java内置工具类(注意版本兼容性)
如果你用的是Java 8及以上,可以用javax.xml.bind.DatatypeConverter的工具方法,但这个类在Java 9+被标记为过时,不过仍可使用:
// 先把所有十六进制字符串拼接成一个无空格的长字符串,比如"0123456789ABCDEF" String fullHex = String.join("", hex); byte[] requiredByte = DatatypeConverter.parseHexBinary(fullHex);
如果是Java 17+,可以用java.util.HexFormat(更推荐,官方新API):
HexFormat hexFormat = HexFormat.of(); byte[] requiredByte = hexFormat.parseHex(String.join("", hex));
为什么你的原方法会出错?
你的hexToBinary方法可能没有生成完整的8位二进制字符串(比如报错里的"100011"只有6位),而且Byte.parseByte()解析二进制字符串时,会把第一位当作符号位,所以10001001这样的二进制串会被解析为-119,但如果字符串长度不对或者方法逻辑有误,就会抛出范围异常。直接跳过二进制字符串的转换步骤,能避免这类问题。
内容的提问来源于stack exchange,提问作者zilijonas

