Строковые преобразования и локали на Android - PullRequest
0 голосов
/ 30 марта 2011

У меня есть приложение для 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 от Apache Commons .

Я пытался переключить свой телефон на немецкий язык, но мои модульные тесты все еще дают правильный результат хеширования. Этот клиент использует стоковую версию Froyo, что исключает риск того, что пользовательское ПЗУ будет здесь ошибочным. Я также нашел эту альтернативу для преобразования из байтов в строку:

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 Ответ

3 голосов
/ 30 марта 2011

В вашем hashDataAsString методе вам нужно сделать hexStringToByteArray?Являются ли входящие данные шестнадцатеричной строкой или просто произвольной строкой?Не могли бы вы использовать String.getBytes ()?

Если вы выполняете строковые / байтовые преобразования, знаете ли вы кодировку входящих данных и предположения кодировки ваших потребителей данных?Вам нужно использовать согласованную кодировку на обоих концах (например, ASCII или UTF-8)?

Включаете ли вы не-ASCII данные в свои модульные тесты?

...