java - 关于字符串编码。
问题描述
public static void main(String[] args) throws Exception { String str = 'resource'; System.out.println(Arrays.toString(getHash(str,'MD5').getBytes()));//使用默认解码后输出}public static String getHash(String str, String hashType) { try {MessageDigest digest = MessageDigest.getInstance(hashType);digest.reset();byte[] b = digest.digest(str.getBytes());System.out.println(Arrays.toString(b)); //编码前输出return new String(b); //使用默认编码 } catch (NoSuchAlgorithmException e) {e.printStackTrace(); } return str;}
输出:[-106, -85, 78, 22, 63, 78, -32, 58, -86, 77, 16, 81, -86, 81, -46, 4]
[-17, -65, -67, -17, -65, -67, 78, 22, 63, 78, -17, -65, -67, 58, -17, -65, -67, 77, 16, 81, -17, -65, -67, 81, -17, -65, -67, 4]
为什么编码前和编码后再解码所输出的不一样?
问题解答
回答1:你可能认为(new String(b)).getBytes().equals(b),实际上并非如此。(尽管new String(s.getBytes()).equals(s)一定是。)
因为byte[]转换成String时,有些字节是未必能转换成字符的,比如第一个-106、第二个-85就是,所以转换成String时前两个就变成了未知字符(表面上会显示?,但实际上是一个Unicode字符),再转成byte[](你这边defaultCharset应该是UTF-8吧),每个未知字符就变成3个字节了。
如果用GBK的话,情况还算好,但还是略有不同:
[-106, -85, 78, 22, 63, 78, -32, 58, -86, 77, 16, 81, -86, 81, -46, 4][-106, -85, 78, 22, 63, 78, 63, 58, -86, 77, 16, 81, -86, 81, 63, 4]
所以结论是:如果用String表示一个Hash值,不能把byte[]强转换成String,而是按惯例转换成16进制表示。
相关文章:
1. android - NavigationView 的侧滑菜单中如何保存新增项(通过程序添加)2. 微信小程序可以用gulp,webpack吗?3. python - 为什么正常输出中文没有乱码,zip函数之后出现中文编程unicode编码的问题,我是遍历输出的啊。4. tp5 不同控制器中的变量调用问题5. ueditor上传服务器提示后端配置项没有正常加载,求助!!!!!6. php7.3.4中怎么开启pdo驱动7. 提示语法错误语法错误: unexpected ’abstract’ (T_ABSTRACT)8. 这段代码既不提示错误也看不到结果,请老师明示错在哪里,谢谢!9. mysql服务无法启动1067错误,谁知道正确的解决方法?10. 老师 我是一个没有学过php语言的准毕业生 我希望您能帮我一下
