Java如何对十六进制数值本身做SHA-256哈希而非哈希其字符串形式
问题根因
你的代码错误点在于直接对十六进制字符串的UTF-8编码结果做哈希,而需求是对十六进制字符串代表的原始二进制数值做哈希,所以核心步骤是先把十六进制串转换为对应的二进制字节数组,再对字节数组做哈希计算。
这里要额外注意:不要直接用new BigInteger(纯十六进制串,16).toByteArray()转换字节数组,若十六进制最高位为1,BigInteger会自动补一个前导0字节表示正数,会导致哈希结果错误,用手动实现的十六进制转字节方法更稳妥。
修复方案
完整可运行代码
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.math.BigInteger; public class Main { // 纯十六进制字符串转字节数组工具方法 public static byte[] hexToBytes(String hexStr) { int len = hexStr.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4) + Character.digit(hexStr.charAt(i+1), 16)); } return data; } public static void main (String[] args) throws NoSuchAlgorithmException { String hex = "0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4139"; // 移除所有空格 hex = hex.replaceAll("\\s+", ""); System.out.println("Hash the Hexadecimal number: " + hex); // 移除0x前缀得到纯十六进制字符 String pureHex = hex.substring(2); // 转换为对应二进制字节数组 byte[] rawBytes = hexToBytes(pureHex); MessageDigest md = MessageDigest.getInstance("SHA-256"); // 对原始二进制字节做哈希计算 md.update(rawBytes); byte[] digest = md.digest(); String hash = String.format("%064x", new BigInteger(1, digest)); System.out.println("Hash of the hex: " + hash); } }
运行输出
Hash the Hexadecimal number: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364139 Hash of the hex: af30ef0d050f65f9b62099fb4fdd9a8859e95495f0737ab442578ef96d61ceae
与预期正确输出完全一致。
内容的提问来源于stack exchange,提问作者Lakshitha Kanchana
相关产品推荐
相关产品推荐

