为何我的SHA-256转换结果与在线工具不一致?
为什么你的SHA-256加密输出是乱码?
嗨,这个问题我刚接触加密的时候也踩过坑!核心原因是你对SHA-256生成的结果处理方式和在线工具不一样~
问题根源
- 你的代码里,
sha256.digest(input.getBytes())返回的是原始二进制字节数组,这些字节包含大量非打印字符(比如ASCII值不在可打印范围内的字节)。直接用new String(output)把二进制字节转成字符串时,这些不可打印的字节就会被显示成乱码或者占位符(就是你看到的<�$=P...)。 - 而在线工具输出的
3CC2243D50E87857A233965AA6B68B37563BFCC52B3C499FBB259B9AA87FFF40,是把原始二进制字节做了**十六进制编码(Hex Encoding)**后的结果——每个字节被转换成两个0-9、A-F的字符,这样整个结果都是可打印的字符串,方便展示和存储。
修正后的代码
这里给你两种常用的修正方法,都能得到和在线工具一致的结果:
方法一:手动实现十六进制转换(兼容所有Java版本)
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class SHA256Example { public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); String input = "00010966776006953D5567439E5E39F86A0D273BEE"; byte[] output = sha256.digest(input.getBytes()); StringBuilder hexResult = new StringBuilder(); for (byte b : output) { // 把字节转为无符号的十六进制字符串 String hex = Integer.toHexString(0xFF & b); // 单个字符的十六进制补前导0 if (hex.length() == 1) { hexResult.append('0'); } hexResult.append(hex); } // 转成大写和在线工具结果一致,小写的话去掉toUpperCase()即可 System.out.println(hexResult.toString().toUpperCase()); } }
方法二:用Java 17+的HexFormat(更简洁)
如果你的项目用的是Java 17及以上版本,可以直接用JDK自带的HexFormat类,代码更简洁:
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HexFormat; public class SHA256Example { public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); String input = "00010966776006953D5567439E5E39F86A0D273BEE"; byte[] output = sha256.digest(input.getBytes()); // 生成大写的十六进制字符串,小写的话去掉withUpperCase() System.out.println(HexFormat.of().withUpperCase().formatHex(output)); } }
总结
记住:加密算法生成的原始结果都是二进制字节,如果你需要可读的字符串,一定要做对应的编码转换(最常用的就是十六进制编码,有时候也会用Base64,但SHA-256的在线工具一般默认用十六进制)。
内容的提问来源于stack exchange,提问作者David says Reinstate Monica
相关产品推荐
相关产品推荐

