【问题标题】:String transformations and locales on AndroidAndroid 上的字符串转换和语言环境
【发布时间】:2011-03-30 11:55:20
【问题描述】:

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

  1. 将字符串转换为字节数组
  2. 使用 MessageDigest 类生成哈希
  3. 将生成的哈希转换回字符串

对于 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 是否更安全?

【问题讨论】:

    标签: java android md5 hash


    【解决方案1】:

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

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

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

    【讨论】:

    • 散列的数据在 SOAP 消息中传递。传递的数据是这样的字符串:“e24566cc6fde36d9bae6f5fda2a95e9d”。此字符串与其他几个字符串连接,然后由我的应用程序散列。我没有在单元测试中包含非 ASCII 数据,因为我没有预料到。我想我确实需要一致的编码来产生一个两边都匹配的哈希。我的代码试图复制这个 Python 代码,但是在 Java/Android 中(向下滚动到“def startSession”):github.com/tachang/EyeFiServer/blob/master/Release%202.0/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多