【问题标题】:String.getBytes("UTF-8") is not platform independent?String.getBytes("UTF-8") 不是独立于平台的吗?
【发布时间】:2013-11-20 22:58:27
【问题描述】:

我正在尝试对我的字符串进行哈希处理并得出以下代码:

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
import sun.misc.BASE64Encoder;

public class JavaTest {
    public static void main (String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String rawString = "9498131529";
        System.out.println(Charset.defaultCharset());
        System.out.println(rawString);

        MessageDigest digest = MessageDigest.getInstance("MD5");
        digest.update(rawString.getBytes("UTF-8")); 
        BASE64Encoder encoder = new BASE64Encoder();
        byte hashedBytes[] = (new String(digest.digest(), "UTF-8")).getBytes();
        System.out.println(encoder.encode(hashedBytes));
    }
}

我的印象是这段代码应该与平台无关,因为当我尝试从字符串中获取字节时,我指定了编码类型“UTF-8”。

但是当我在我的 Mac、Dev 环境和 staging 环境上运行代码时,我得到了以下结果: Mac

MacRoman
9498131529
XElaLD8UPzE/P1sWDz8/Pw==

开发人员:

US-ASCII
9498131529
XElaLD8UPzE/P1sWDz8/Pw==

暂存

UTF-8
9498131529
XElaLO+/vRTvv70x77+977+9WxYP77+977+977+9

我的配置:

Mac

> sw_vers
ProductName:    Mac OS X
ProductVersion: 10.9
BuildVersion:   13A603

开发

> cat /proc/version
Linux version 2.6.21.7-2.fc8xen-ec2-v1.0  (gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)) #2 SMP Tue Sep 1 10:04:29 EDT 2009

暂存

> cat /proc/version
Linux version 3.2.0-31-virtual (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #50-Ubuntu SMP Fri Sep 7 16:36:36 UTC 2012

我在这里缺少什么?为什么哈希算法系统是独立的?而且我相信 MD5 根据规范应该是平台无关的。我的假设错了吗?

如果您需要更多详细信息,请告诉我!

【问题讨论】:

  • 将摘要往返于字符串 (new String(digest.digest(), "UTF-8").getBytes()) 的步骤看起来很可疑。 (而且不必要 - 您可能应该对摘要本身进行 base-64。)事实上,摘要可能不是有效的 UTF-8,您看到的可能是不同的解码错误处理。
  • 实际上,等等,这可能正是问题所在。不带参数的.getBytes() 将字符串编码为默认字符集,MacRoman 和 US-ASCII 可能非常相似,可以巧合地给出相同的结果。使用.getBytes("UTF-8") 应该让你在任何地方都有相同的行为,但这仍然是错误的做法。
  • @millimoose 感谢您的意见! :) 我猜 Stefan 打败了你。

标签: java string encoding utf-8 character-encoding


【解决方案1】:

为什么要通过 String 进行额外的往返?即使您在 getBytes() 中添加“UTF-8”,它仍然是错误的,因为它将原始字节数组(摘要)视为 UTF-8 编码的字符串。

将 hashedBytes 行更改为:

    byte hashedBytes[] = digest.digest();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-14
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 2012-01-25
    相关资源
    最近更新 更多