Java Android上的字符串转换和区域设置

Java Android上的字符串转换和区域设置,java,android,md5,hash,Java,Android,Md5,Hash,我有一个Android应用程序,它是客户机/服务器设计中的“服务器”。在应用程序中,我需要根据一组字符串计算MD5哈希,并将结果返回给客户端,以便让它们之间的对话继续。我的代码是从众多的例子中拼凑而成的。计算散列的算法(不是我设计的)如下: 将字符串转换为字节数组 使用MessageDigest类生成哈希 将结果哈希转换回字符串 对于我99%的客户来说,哈希似乎是正确的。其中一位客户看到错误的哈希值是在德国地区运行的,这让我开始怀疑语言是否会影响我得到的结果。这是从字符串中生成字节数组的代码:

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

  • 将字符串转换为字节数组
  • 使用MessageDigest类生成哈希
  • 将结果哈希转换回字符串
  • 对于我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;
    }
    
    我在用电话

    我尝试将手机切换到德国地区,但我的单元测试仍然会产生正确的哈希结果。该客户使用的是库存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是否更安全?

    在您的
    hashDataAsString
    方法中,是否需要执行
    HextStringToByteArray
    ?传入的数据是十六进制字符串还是任意字符串?不能使用String.getBytes()吗

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


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

    hashDataAsString
    方法中,是否需要执行
    hextStringToByteArray
    ?传入的数据是十六进制字符串还是任意字符串?不能使用String.getBytes()吗

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


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

    散列的数据在SOAP消息中传递。传递的数据是这样的字符串:“e24566cc6fde36d9bae6f5fda2a95e9d”。此字符串与其他几个字符串连接,然后由我的应用程序进行散列。我没有在单元测试中包含非ASCII数据,因为我没有预料到这一点。我想我确实需要一致的编码来产生一个两边都匹配的散列。我的代码试图复制此Python代码,但在Java/Android中(向下滚动到“def startSession”):散列的数据在SOAP消息中传递。传递的数据是这样的字符串:“e24566cc6fde36d9bae6f5fda2a95e9d”。此字符串与其他几个字符串连接,然后由我的应用程序进行散列。我没有在单元测试中包含非ASCII数据,因为我没有预料到这一点。我想我确实需要一致的编码来产生一个两边都匹配的散列。我的代码试图复制此Python代码,但在Java/Android中(向下滚动至“def startSession”):
    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;
    }