Android上的字符串转换和语言环境

时间:2011-03-30 11:55:20

标签: java android md5 hash

我有一个Android应用程序,它是客户端/服务器设计中的“服务器”。在应用程序中,我需要针对一组字符串计算MD5哈希并将结果返回给客户端,以便让它们之间的对话继续。我这样做的代码已经从众多例子拼凑而成。计算哈希的算法(不是由我设计)是这样的:

  1. 将字符串转换为字节数组
  2. 使用MessageDigest类生成哈希
  3. 将生成的哈希转换回字符串
  4. 哈希似乎对99%的客户都是正确的。其中一个看到错误哈希的客户正在使用德语语言环境运行,它开始让我想知道语言是否可以考虑到我得到的结果。这是使字节数组不在字符串中的代码:

        public static byte[] hexStringToByteArray(String s) 
        {
            byte[] data = null;
    
            if(s.length() % 2 != 0)
            {
                s = "0" + s;
            }
    
            int len = s.length();
            data = new byte[len / 2];
    
            for (int i = 0; i < len; i += 2) 
            {
                data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                     + Character.digit(s.charAt(i+1), 16));
            }
    
            return data;
    }
    

    这是散列函数的当前版本:

    public static String hashDataAsString(String dataToHash)
    {
        MessageDigest messageDigest;
        try
        {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            byte[] data = hexStringToByteArray(dataToHash);
            messageDigest.update(data);
            final byte[] resultByte = messageDigest.digest();
            return new String(Hex.encodeHex(resultByte));
        }
        catch(NoSuchAlgorithmException e)
        {
            throw new RuntimeException("Failed to hash data values", e);
        }
    }
    

    我正在使用Hex.encodeHex function from Apache Commons

    我尝试将手机切换到德语区域设置,但我的单元测试仍会产生正确的哈希结果。该客户使用的是Froyo库存,因此可以消除自定义ROM出现故障的风险。我还发现了从字节转换为字符串的替代方法:

    public static String MD5_Hash(String s) {
            MessageDigest m = null;
    
            try {
                    m = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
            }
    
            //m.update(s.getBytes(),0,s.length());
            byte [] data = hexStringToByteArray(s);
            m.update(data, 0, data.length);
            String hash = new BigInteger(1, m.digest()).toString(16);
            return hash;
    }
    

    在我的单元测试中,它会产生相同的答案。 BigInteger可以在这里使用更安全吗?

1 个答案:

答案 0 :(得分:3)

hashDataAsString方法中,您需要hexStringToByteArray吗?传入数据是十六进制字符串还是只是一个任意字符串?你能不能使用String.getBytes()?

如果您正在进行字符串/字节转换,您是否知道传入数据的编码和数据使用者的编码假设?您是否需要在两端使用一致的编码(例如ASCII或UTF-8)?

您是否在单元测试中包含非ASCII数据?