Java - хэш-алгоритмы - самые быстрые реализации - PullRequest
29 голосов
/ 27 марта 2011

Я хочу знать, какова лучшая и самая быстрая реализация алгоритмов хеширования для Java, особенно MD5 и SHA-2 512 (SHA512) или 256. Я хочу, чтобы функция получала строку в качестве аргумента и возвращала хеш в качестве результата , Спасибо тебе.

Редактировать: для отображения каждого URL на уникальный хеш. Поскольку MD5 не настолько надежен в этой области, меня больше интересует поиск наилучшей и быстрой реализации алгоритмов SHA-2. Обратите внимание, что я знаю, что даже SHA-2 может выдавать один и тот же хеш для некоторых URL, но я могу с этим смириться.

Ответы [ 6 ]

49 голосов
/ 28 марта 2011

Перво-наперво: скорость переоценена.Вы должны принять меры, прежде чем объявить, что данный алгоритм «слишком медленный».В большинстве случаев скорость хеш-функции не имеет никакого значения.Если вы сомневаетесь в безопасности, то сначала выберите хеш-функцию, которая достаточно безопасна, а затем беспокоитесь только о производительности.

Более того, вы хотите хешировать «строки».Java String внутренне является порцией из массива char значений, которые представляют кодовые точки Unicode (фактически, 16-битные кодовые единицы Unicode, которые кодируют кодовые точки с использованием UTF-16).Хеш-функция принимает в качестве входных данных последовательность битов или байтов.Таким образом, вам нужно будет выполнить шаг преобразования, например, str.getBytes("UTF-8"), чтобы получить строку в виде байтов.Вполне вероятно, что шаг преобразования будет иметь незначительную стоимость по сравнению с самим хэшированием.

Примечание: остерегайтесь кодировки URL!В URL некоторые байты могут быть заменены последовательностями, начинающимися со знака «%»;это предназначено для поддержки непечатаемых символов, но может использоваться и для «стандартных» символов (например, замена 'a' на '%61').Это означает, что две строки, которые различны (в смысле String.equals()), могут фактически представлять один и тот же URL (что касается обработки URL).В зависимости от вашей ситуации это может или не может быть проблемой.

Сначала вы должны попытаться использовать Java MessageDigest API со стандартным (уже установленным) поставщиком JCE (т.е. вы звоните MessageDigest.getInstance("SHA-256")), исравнить результат.Теоретически, JCE может сопоставить вызов реализации с "собственным" кодом (написанным на C или сборке), который будет быстрее, чем то, что вы можете получить с помощью Java.

При этом ...

sphlib - это реализация многих криптографических хеш-функций с открытым исходным кодом на C и Java.Код был оптимизирован для скорости, и на практике версия Java оказывается быстрее, чем стандартная JRE от Sun / Oracle.Используйте эту ссылку в случае сбоя предыдущей ссылки (главный хост-сервер иногда не работает из-за технического обслуживания, как это, похоже, происходит сейчас) (предупреждение: загрузка 10 МБ).В архиве также содержится отчет (который был представлен на второй конференции кандидатов SHA-3 в 2010 году), в котором приведены некоторые измеренные показатели производительности на нескольких платформах для SHA-2 и 14 кандидатов во «второй раунд» дляпредстоящий SHA-3.

Но вы действительно должны сделать тесты на месте.Например, влияние на кэш L1 может сильно повлиять на производительность и не может быть точно предсказано, если взять код функции и запустить его изолированно.

21 голосов
/ 27 марта 2011

Редактировать: Первоначально я прочитал вопрос как «самый быстрый алгоритм хеширования», и было пояснено, что это «самая быстрая реализация каждого алгоритма».Это правильный вопрос, и другие указали на более быстрые реализации.Однако, если вы за короткое время хешируете большие объемы данных, это не будет иметь большого значения.Я сомневаюсь, что обычно стоит потраченного времени и сложности, чтобы использовать что-то отличное от того, что предусмотрено в стандартном JCE.

Для URL-адресов вам потребуется хэшировать SHA-256 со скоростью выше миллионов в секунду на современном оборудовании требуется что-то быстрее.Я не могу представить себе, что большинству приложений требуется более тысячи в секунду (более 86 миллионов в день), а это означает, что общее время, затрачиваемое на хэширование процессора, будет намного меньше 1%.Таким образом, даже если бы у вас был бесконечно быстрый алгоритм хэширования, вы могли бы улучшить общую производительность только в лучшем случае на 1%.

Оригинальный ответ: Получение как лучших, так и самых быстрых шансовдруг с другом.Чем лучше хэши, тем медленнее.Если вам действительно нужна скорость и безопасность не так важна, используйте MD5.Если вам нужна лучшая защита, тогда используйте SHA-256 или даже SHA-512.Вы не упомянули, для чего вы его используете, поэтому трудно рекомендовать одно или другое.Вы, вероятно, наиболее безопасны в использовании SHA-256, так как в любом случае он должен быть достаточно быстрым для большинства случаев использования на современном оборудовании.Вот как вы можете это сделать:

String input = "your string";
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(input.getBytes("UTF-8"));
byte[] hash = digest.digest();

Если вы используете это в целях безопасности, например, для хеширования пароля, то вам следует добавить соль и в дайджест.Если вы хотите, чтобы из хеша была напечатана строка, вы можете закодировать ее обратно в строку как шестнадцатеричное:

static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();

StringBuilder sb = new StringBuilder(hash.length * 2);
for (byte b : hash) {
    sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
    sb.append(HEX_CHARS[b & 0x0F]);
}
String hex = sb.toString();
2 голосов
/ 27 марта 2011

Еще одна вещь, которую следует учитывать, это использование MD4. Это не так безопасно, как MD5, но вычисляется еще быстрее. Windows до XP использовалась для хранения и обмена паролями в MD4, поэтому мы используем этот хэш, поскольку он все еще позволяет нам предоставлять услуги аутентификации для этой платформы.

2 голосов
/ 27 марта 2011

Проверьте это: Множество примеров SHA / MD5

Также: Из той же нити: Fast MD5

Строковый хэш = MD5.asHex (MD5.getHash (новый файл (имя файла)));

1 голос
/ 30 мая 2018

Рассмотрим BLAKE2, который работает быстрее и надежнее, чем упомянутые выше хэши.

MD5, SHA-1, SHA256 и SHA-512 подвержены удлинению по длине.

MD5 иSHA-1 уязвимы для коллизий.

MD5 уязвим для коллизий с выбранным префиксом.

SHA-3 и BLAKE2 не имеют известных проблем безопасности и могут генерировать дайджесты различной длины.

SHA-3 является самым быстрым при реализации на аппаратном уровне;BLAKE2 является самым быстрым при использовании программных реализаций.

BLAKE2b оптимизирован для 64-битных платформ и создает дайджесты любого размера от 1 до 64 байтов.

BLAKE2s оптимизирован для 8–32-битных платформи создает дайджесты любого размера от 1 до 32 байт.

Вот тесты для AES, MD5, SHA-256 и BLAKE2b.

https://blake2.net/

https://www.cryptopp.com/benchmarks.html

В первой ссылке BLAKE2b (947 Мбит) намного быстрее, чем SHA-256 (413 Мбит) и MD5 (632 Мбит).

Во второй ссылке AES-256 CBC(805 Мбит) и BLAKE2b (776 Мбит) примерно равны по скорости и быстрее, чем SHA-256 (275 Мбит) и MD5 (602) Мбит.

0 голосов
/ 24 апреля 2016

Для строки просто вызовите hashCode(), так как она требует меньших затрат памяти.

В противном случае я рекомендую этот код для частного хэша:

public static int hash8(String val) throws UnsupportedEncodingException {
    return hash8(val.getBytes("UTF-8"));
}

public static int hash8(byte[] val) {
    int h = 1, i = 0;
    for (; i + 7 < val.length; i += 8) {
        h = 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * 31
                * 31 * 31 * 31 * val[i] + 31 * 31 * 31 * 31 * 31 * 31
                * val[i + 1] + 31 * 31 * 31 * 31 * 31 * val[i + 2] + 31
                * 31 * 31 * 31 * val[i + 3] + 31 * 31 * 31 * val[i + 4]
                + 31 * 31 * val[i + 5] + 31 * val[i + 6] + val[i + 7];
    }
    for (; i + 3 < val.length; i += 4) {
        h = 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * val[i] + 31 * 31
                * val[i + 1] + 31 * val[i + 2] + val[i + 3];
    }
    for (; i < val.length; i++) {
        h = 31 * h + val[i];
    }
    return h;
}

FYI: http://lemire.me/blog/2015/10/22/faster-hashing-without-effort/

...