Вычислить хеш, выполнив одно из следующих действий:
Подайте весь ввод как a byte[]и вычислите хеш за одну операцию с md.digest(bytes).
Накорми MessageDigestодин byte[]кусок за раз, позвонив md.update(bytes). Когда вы закончите добавлять входные байты, вычислите хеш с помощью
md.digest().
Одна вещь, которая здесь не упоминается, и застала меня врасплох. Классы MessageDigest НЕ являются потокобезопасными. Если они будут использоваться разными потоками, просто создайте новый, а не пытайтесь использовать их повторно.
mjuarez
39
Он использует несколько методов для изменения своего внутреннего состояния. Как отсутствие безопасности потоков может быть удивительным?
Бомба
90
@Bombe: почему мы должны знать о внутреннем состоянии MessageDigest?
Дэн Барови
28
@DanBarowy ну, которые мутируют его (то есть вызов методов , которые не возвращают значения , но вызывают другие методы , чтобы возвращать разные значения) , так что до тех пор , пока не доказано обратное , вы всегда должны предполагать , что это не поточно-сделать это.
Бомба
3
@Traubenfuchs MessageDigest позволяет вводить данные кусками. Это было бы невозможно с помощью статического метода. Хотя вы можете утверждать, что они должны были добавить один в любом случае для удобства, когда вы можете передать все данные одновременно.
user253751
690
MessageDigestКласс может предоставить вам экземпляр MD5 дайджеста.
При работе со строками и криптографическими классами обязательно всегда указывайте кодировку, в которой вы хотите байтовое представление. Если вы просто используете string.getBytes()его, будет использоваться платформа по умолчанию. (Не все платформы используют одинаковые значения по умолчанию)
Этот раздел также полезен, если вам нужно преобразовать полученные байты в шестнадцатеричную строку.
Weekens
1
Тогда как вы преобразуете этот дайджест в строку, чтобы мы могли вставить ее в mysql?
Хамфри
2
А еще лучше, где это возможно yourString.getBytes(StandardCharsets.UTF_8). Это предотвращает обработку UnsupportedEncodingException.
Hummeling Engineering BV
267
Если вы действительно хотите получить ответ в виде строки, а не байтового массива, вы всегда можете сделать что-то вроде этого:
String plaintext ="your text here";MessageDigest m =MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());byte[] digest = m.digest();BigInteger bigInt =newBigInteger(1,digest);String hashtext = bigInt.toString(16);// Now we need to zero pad it if you actually want the full 32 chars.while(hashtext.length()<32){
hashtext ="0"+hashtext;}
@BalusC: Не верно, метод BigInteger.toString вернет полное число в указанной базе. 0x0606 будет напечатано как 606, пропущены только конечные нули,
Spidey
11
Незначительная мелочь: m.reset () не нужен сразу после вызова getInstance. Более незначительный: «ваш текст здесь» требует двойных кавычек.
Дэвид Леппик
Начиная с Java 11, вы можете использовать hashtext = "0".repeat(32 - hashtext.length()) + hashtextвместо while, так что редакторы не будут предупреждать вас о том, что вы выполняете конкатенацию строк внутри цикла.
Том
Вместо m.update (plaintext.getBytes ()); Я бы порекомендовал указать кодировку. такой как m.update (plaintext.getBytes ("UTF-8")); getBytes () не гарантирует кодирование и может варьироваться от системы к системе, что может привести к разным результатам MD5 между системами для одной и той же строки.
user1819780
256
Возможно, вы также захотите взглянуть на класс DigestUtils проекта кодека Apache Commons , который предоставляет очень удобные методы для создания дайджестов MD5 или SHA.
В частности, методы, которые возвращают «безопасные» закодированные представления байтовых данных в виде строки.
Роб
4
Однако не существует простого способа вставить класс DigestUtils в ваш проект без добавления тонны библиотек или портирования класса «на руку», который требует как минимум еще двух классов.
iuiz
Не могу найти его и в репозиториях Maven. Grrrr.
sparkyspider
5
Должно быть в центральных репозиториях Maven, если только я не схожу с ума: groupId = commons-codec artifactId = commons-codec version = 1.5
Ник Спейсек,
160
Нашел это:
publicString MD5(String md5){try{
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");byte[] array = md.digest(md5.getBytes());StringBuffer sb =newStringBuffer();for(int i =0; i < array.length;++i){
sb.append(Integer.toHexString((array[i]&0xFF)|0x100).substring(1,3));}return sb.toString();}catch(java.security.NoSuchAlgorithmException e){}returnnull;}
на сайте ниже, я не беру на себя ответственность, но это решение, которое работает! Для меня много другого кода не работает должным образом, я потерял 0 в хэше. Это похоже на то, что есть в PHP. источник: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093
Вы должны указать кодировку, которая будет использоваться getBytes(), иначе ваш код получит разные результаты на разных платформах / пользовательских настройках.
Paŭlo Ebermann
@ PaŭloEbermann делает MessageDigest.getInstance ("MD5"); недостаточно? Я попытался добавить «MD5» в getBytes (), но он вернул ошибку
Blaze Tama
2
@BlazeTama "MD5" - это не кодировка, это алгоритм дайджеста сообщений (а не тот, который следует использовать в новых приложениях). Кодировка - это пара алгоритмов, которая преобразует байты в строки, а строки в байты. Примером могут быть «UTF-8», «US-ASCII», «ISO-8859-1», «UTF-16BE» и аналогичные. Используйте ту же кодировку, что и для любой другой стороны, которая вычисляет хэш этой строки, иначе вы получите другие результаты.
Паŭло Эберманн
6
Для примера набора символов ... (используйте UTF-8, который является лучшим и наиболее совместимым на мой взгляд) ...byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
Ричард
Поскольку это не мое решение, и я сам не тестировал все сценарии, я оставлю его без изменений, хотя я думаю, что задание кодировки и т. Д., Вероятно, хорошая идея.
dac2009
88
Вот как я это использую:
finalMessageDigest messageDigest =MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(string.getBytes(Charset.forName("UTF8")));finalbyte[] resultByte = messageDigest.digest();finalString result =newString(Hex.encodeHex(resultByte));
где Hex: org.apache.commons.codec.binary.Hexиз проекта Apache Commons .
Этот метод предоставляет то же возвращаемое значение, что и функция MySQL md5 (str). Многие другие ответы вернули другие значения.
rwitzel
1
Это не работает должным образом на Android, потому что Android объединяет commons-codec 1.2, для которого вам нужен этот обходной путь: stackoverflow.com/a/9284092/2413303
EpicPandaForce
76
Я обнаружил, что это самый понятный и лаконичный способ сделать это:
Отлично. Это не попадает в ловушку сокращения ведущих нулей.
Маркус Пшеидт
2
Остерегайтесь, это не будет работать для Android, если вы используете API уровня <19, но вам просто нужно изменить вторую строку с помощью md5.update (string.getBytes ("UTF-8")); Это добавит еще одно проверенное исключение для обработки, хотя ...
Fran Marzoa
34
Нашел это решение, которое намного чище с точки зрения получения представления String из хеша MD5.
import java.security.*;import java.math.*;publicclass MD5 {publicstaticvoid main(String args[])throwsException{String s="This is a test";MessageDigest m=MessageDigest.getInstance("MD5");
m.update(s.getBytes(),0,s.length());System.out.println("MD5: "+newBigInteger(1,m.digest()).toString(16));}}
Почему этот ответ равен -1, а другой, более короткий и менее описательный ответ имеет +146?
Нильзор
4
Хорошо использовать BigInteger, чтобы получить шестнадцатеричное значение +1
Dave.B
5
Я только что узнал, что в некоторых случаях это генерирует только сумму MD5 из 31 символа, а не 32, как должно быть
kovica
3
@kovica это потому, что начальные нули обрезаются, если я правильно помню .. String.format("%032x", new BigInteger(1, hash)); Это должно решить эту проблему. 'hash' - это байт [] хэша.
Я видел только одну строку, которая не использует внешнюю библиотеку.
holmis83
Если я не ошибаюсь, это всегда возвращает в верхнем регистре, который не будет совпадать с md5, сделанным без использования hex. Даже не совсем уверен, что это настоящий md5
walshie4
2
@ walshie4 нет MD5 без hex (см. ietf.org/rfc/rfc1321.txt ), чтобы получить его строчными буквами, просто добавьте .toLower (). Сравните результаты с примерами, например, в en.wikipedia.org/wiki/MD5, и у вас будет больше шансов поверить в правильность кода библиотеки Javas.
укладчик
28
У меня есть класс (хэш) для преобразования обычного текста в хэш в форматах: md5 или sha1, схожие функции php ( md5 , sha1 ):
publicclassHash{/**
*
* @param txt, text in plain format
* @param hashType MD5 OR SHA1
* @return hash in hashType
*/publicstaticString getHash(String txt,String hashType){try{
java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);byte[] array = md.digest(txt.getBytes());StringBuffer sb =newStringBuffer();for(int i =0; i < array.length;++i){
sb.append(Integer.toHexString((array[i]&0xFF)|0x100).substring(1,3));}return sb.toString();}catch(java.security.NoSuchAlgorithmException e){//error action}returnnull;}publicstaticString md5(String txt){returnHash.getHash(txt,"MD5");}publicstaticString sha1(String txt){returnHash.getHash(txt,"SHA1");}}
Ответ Bombe является правильным, однако учтите, что, если вам абсолютно не нужно использовать MD5 (например, навязанный вам для обеспечения совместимости), лучшим выбором будет SHA1, поскольку MD5 имеет недостатки для долгосрочного использования.
Я должен добавить, что SHA1 также имеет теоретические уязвимости, но не такие серьезные. Современное состояние хэширования состоит в том, что существует ряд возможных хэш-функций для замены, но ни одна из них еще не стала стандартной передовой практикой для замены SHA1. Таким образом, в зависимости от ваших потребностей, вам бы лучше сделать настраиваемый алгоритм хеширования, чтобы в будущем его можно было заменить.
Не могли бы вы указать мне некоторые ресурсы, где я могу прочитать об относительных достоинствах и недостатках каждого из них?
Акшай
Вероятно, лучшее, что вы можете сделать в данный момент, это использовать SHA1 и быть готовым заменить его в будущем. Вы можете использовать новые функции, но они еще не были предметом большого количества исследований. Вы можете отслеживать ресурсы онлайн-безопасности, чтобы узнать, когда это изменится - например, блог Брюса Шнайера.
frankodwyer
7
SHA1 является избыточным, если вам не нужен криптографически безопасный хеш, т.е. вы не хотите, чтобы хеш помогал восстановить исходное сообщение, и при этом вы не хотите, чтобы умный злоумышленник создал другое сообщение, которое соответствует хешу. Если оригинал не секрет и хеш не используется для безопасности, MD5 быстр и прост. Например, Google Web Toolkit использует хеши MD5 в URL-адресах JavaScript (например, foo.js? Hash = 12345).
Это солидная, автономная библиотека с минимальными зависимостями. Хорошая вещь.
Аякс
Я нахожу это очень полезным. Для файла 4,57 ГБ потребовалось 15357 мс, а для встроенной Java-реализации - 19094 мс.
bkrish
11
Я не знаю, относится ли это к любому, кто читает это, но у меня просто была проблема, которую я хотел
загрузить файл с данного URL и
сравните его MD5 с известным значением.
Я хотел сделать это только с классами JRE (без Apache Commons или аналогичных). Быстрый веб-поиск не показал мне примеры фрагментов кода, выполняющих оба одновременно, только каждое задание в отдельности. Поскольку для этого требуется дважды прочитать один и тот же файл, я подумал, что, возможно, стоит написать некоторый код, который объединяет обе задачи, вычисляя контрольную сумму на лету при загрузке файла. Это мой результат (извините, если это не идеальная Java, но я думаю, вы все равно поняли):
О, кстати, прежде чем кто-либо, кроме меня, заметит, насколько плохи мои знания в области JRE: я только что открыл DigestInputStream и DigestOutputStream . Я собираюсь отредактировать свое оригинальное решение, чтобы отразить то, что я только что изучил.
kriegaex
6
Посмотрите на следующую ссылку, Пример получает хеш-код MD5 предоставленного изображения:
Хеш-код MD5 изображения
Что бы это ни стоило, я наткнулся на это, потому что я хочу синтезировать GUID из естественного ключа для программы, которая будет устанавливать компоненты COM; Я хочу изменить размер, чтобы не управлять жизненным циклом GUID. Я использую MD5, а затем использую класс UUID, чтобы получить из него строку. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439 поднимает эту проблему).
В любом случае, java.util.UUID может получить хорошую строку из байтов MD5.
на самом деле он принимает не только массив байтов MD5 (размер == 16). Вы можете передать байтовый массив любой длины. Он будет преобразован в массив байтов MD5 с помощью MD5 MessageDigest(см. Исходный код nameUUIDFromBytes () )
В отличие от PHP, где вы можете выполнять хеширование текста с помощью MD5, просто вызывая функцию md5, т. Е. md5($text)В Java это стало немного сложнее. Я обычно реализовывал это, вызывая функцию, которая возвращает текст хеша md5. Вот как я это реализовал. Сначала создайте функцию с именем md5hashingвнутри вашего основного класса, как показано ниже.
publicstaticString md5hashing(String text){String hashtext =null;try{String plaintext = text;MessageDigest m =MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());byte[] digest = m.digest();BigInteger bigInt =newBigInteger(1,digest);
hashtext = bigInt.toString(16);// Now we need to zero pad it if you actually want the full 32 chars.while(hashtext.length()<32){
hashtext ="0"+hashtext;}}catch(Exception e1){// TODO: handle exceptionJOptionPane.showMessageDialog(null,e1.getClass().getName()+": "+ e1.getMessage());}return hashtext;}
Теперь вызывайте функцию всякий раз, когда вам нужно, как указано ниже.
String text = textFieldName.getText();String pass = md5hashing(text);
Здесь вы можете видеть, что к хеш-тексту добавляется ноль, чтобы он соответствовал хешированию md5 в PHP.
MD5 прекрасно работает, если вам не нужна лучшая защита, и если вы делаете что-то вроде проверки целостности файла, тогда безопасность не имеет значения. В таком случае вы можете рассмотреть что-то более простое и быстрое, например Adler32, который также поддерживается библиотеками Java.
Что заставляет вас думать, что целостность файлов не является проблемой безопасности?
Джереми Хуискамп
5
этот дает точное значение md5, полученное из функции md5 mysql или функций md5 php и т. д. Это то, что я использую (вы можете изменить в соответствии со своими потребностями)
Это, вероятно, худшее решение, поскольку оно убирает лидирующие нули.
Янник
4
import java.security.MessageDigest
val digest =MessageDigest.getInstance("MD5")//Quick MD5 of text
val text ="MD5 this text!"
val md5hash1 = digest.digest(text.getBytes).map("%02x".format(_)).mkString
//MD5 of text with updates
digest.update("MD5 ".getBytes())
digest.update("this ".getBytes())
digest.update("text!".getBytes())
val md5hash2 = digest.digest().map(0xFF& _).map("%02x".format(_)).mkString
//Output
println(md5hash1 +" should be the same as "+ md5hash2)
Выходные данные функции MD5 представляют собой 128-битный хэш, представленный 32 шестнадцатеричными числами.
В случае, если вы используете базу данных, такую как MySQL, вы можете сделать это и более простым способом. Запрос Select MD5(“text here”)вернет MD5-хеш текста в скобках.
Ответы:
Вам нужно
java.security.MessageDigest
.Позвоните,
MessageDigest.getInstance("MD5")
чтобы получить экземпляр MD5, которыйMessageDigest
вы можете использовать.Вычислить хеш, выполнив одно из следующих действий:
byte[]
и вычислите хеш за одну операцию сmd.digest(bytes)
.MessageDigest
одинbyte[]
кусок за раз, позвонивmd.update(bytes)
. Когда вы закончите добавлять входные байты, вычислите хеш с помощьюmd.digest()
.byte[]
Возвращаемыйmd.digest()
является хэш MD5.источник
MessageDigest
позволяет вводить данные кусками. Это было бы невозможно с помощью статического метода. Хотя вы можете утверждать, что они должны были добавить один в любом случае для удобства, когда вы можете передать все данные одновременно.MessageDigest
Класс может предоставить вам экземпляр MD5 дайджеста.При работе со строками и криптографическими классами обязательно всегда указывайте кодировку, в которой вы хотите байтовое представление. Если вы просто используете
string.getBytes()
его, будет использоваться платформа по умолчанию. (Не все платформы используют одинаковые значения по умолчанию)Если у вас много данных, взгляните на
.update(byte[])
метод, который можно вызывать повторно. Затем вызовите,.digest()
чтобы получить полученный хеш.источник
yourString.getBytes(StandardCharsets.UTF_8)
. Это предотвращает обработкуUnsupportedEncodingException
.Если вы действительно хотите получить ответ в виде строки, а не байтового массива, вы всегда можете сделать что-то вроде этого:
источник
hashtext = "0".repeat(32 - hashtext.length()) + hashtext
вместоwhile
, так что редакторы не будут предупреждать вас о том, что вы выполняете конкатенацию строк внутри цикла.Возможно, вы также захотите взглянуть на класс DigestUtils проекта кодека Apache Commons , который предоставляет очень удобные методы для создания дайджестов MD5 или SHA.
источник
Нашел это:
на сайте ниже, я не беру на себя ответственность, но это решение, которое работает! Для меня много другого кода не работает должным образом, я потерял 0 в хэше. Это похоже на то, что есть в PHP. источник: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093
источник
getBytes()
, иначе ваш код получит разные результаты на разных платформах / пользовательских настройках.byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
Вот как я это использую:
где Hex:
org.apache.commons.codec.binary.Hex
из проекта Apache Commons .источник
String result = Hex.encodeHexString(resultByte);
Я только что скачал commons-codec.jar и получил идеальный php как md5. Здесь руководство .
Просто импортируйте его в свой проект и используйте
и вот оно у тебя.
источник
Я обнаружил, что это самый понятный и лаконичный способ сделать это:
источник
Нашел это решение, которое намного чище с точки зрения получения представления String из хеша MD5.
Код был извлечен отсюда .
источник
String.format("%032x", new BigInteger(1, hash));
Это должно решить эту проблему. 'hash' - это байт [] хэша.Другой вариант заключается в использовании методов хэширования гуавы :
Удобно, если вы уже используете Guava (а если нет, то, вероятно, вам следует).
источник
Hashing.md5().hashString("my string").asBytes();
Еще одна реализация:
источник
У меня есть класс (хэш) для преобразования обычного текста в хэш в форматах: md5 или sha1, схожие функции php ( md5 , sha1 ):
Тестирование с помощью JUnit и PHP
PHP скрипт:
Выходной PHP-скрипт:
Используя пример и тестирование с JUnit:
Код в GitHub
источник
Не нужно делать это слишком сложным.
DigestUtils отлично работает и позволяет вам комфортно работать с
md5
хэшами.или
Либо вы можете использовать любые другие методы шифрования, такие как
sha
илиmd
.источник
Мой не очень показательный ответ:
источник
String.format("%1$032X", big)
иметь прописные буквыВесной также есть
DigestUtils
класс :http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/DigestUtils.html
Этот класс содержит метод,
md5DigestAsHex()
который выполняет эту работу.источник
Вы можете попробовать следующее. Подробности и коды для скачивания смотрите здесь: http://jkssweetlife.com/java-hashgenerator-md5-sha-1/
источник
Ответ Bombe является правильным, однако учтите, что, если вам абсолютно не нужно использовать MD5 (например, навязанный вам для обеспечения совместимости), лучшим выбором будет SHA1, поскольку MD5 имеет недостатки для долгосрочного использования.
Я должен добавить, что SHA1 также имеет теоретические уязвимости, но не такие серьезные. Современное состояние хэширования состоит в том, что существует ряд возможных хэш-функций для замены, но ни одна из них еще не стала стандартной передовой практикой для замены SHA1. Таким образом, в зависимости от ваших потребностей, вам бы лучше сделать настраиваемый алгоритм хеширования, чтобы в будущем его можно было заменить.
источник
Другая реализация: быстрая реализация MD5 в Java
источник
Я не знаю, относится ли это к любому, кто читает это, но у меня просто была проблема, которую я хотел
Я хотел сделать это только с классами JRE (без Apache Commons или аналогичных). Быстрый веб-поиск не показал мне примеры фрагментов кода, выполняющих оба одновременно, только каждое задание в отдельности. Поскольку для этого требуется дважды прочитать один и тот же файл, я подумал, что, возможно, стоит написать некоторый код, который объединяет обе задачи, вычисляя контрольную сумму на лету при загрузке файла. Это мой результат (извините, если это не идеальная Java, но я думаю, вы все равно поняли):
источник
Посмотрите на следующую ссылку, Пример получает хеш-код MD5 предоставленного изображения: Хеш-код MD5 изображения
источник
Что бы это ни стоило, я наткнулся на это, потому что я хочу синтезировать GUID из естественного ключа для программы, которая будет устанавливать компоненты COM; Я хочу изменить размер, чтобы не управлять жизненным циклом GUID. Я использую MD5, а затем использую класс UUID, чтобы получить из него строку. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439 поднимает эту проблему).
В любом случае, java.util.UUID может получить хорошую строку из байтов MD5.
источник
MessageDigest
(см. Исходный код nameUUIDFromBytes () )источник
В отличие от PHP, где вы можете выполнять хеширование текста с помощью MD5, просто вызывая функцию md5, т. Е.
md5($text)
В Java это стало немного сложнее. Я обычно реализовывал это, вызывая функцию, которая возвращает текст хеша md5. Вот как я это реализовал. Сначала создайте функцию с именемmd5hashing
внутри вашего основного класса, как показано ниже.Теперь вызывайте функцию всякий раз, когда вам нужно, как указано ниже.
Здесь вы можете видеть, что к хеш-тексту добавляется ноль, чтобы он соответствовал хешированию md5 в PHP.
источник
MD5 прекрасно работает, если вам не нужна лучшая защита, и если вы делаете что-то вроде проверки целостности файла, тогда безопасность не имеет значения. В таком случае вы можете рассмотреть что-то более простое и быстрое, например Adler32, который также поддерживается библиотеками Java.
источник
этот дает точное значение md5, полученное из функции md5 mysql или функций md5 php и т. д. Это то, что я использую (вы можете изменить в соответствии со своими потребностями)
источник
попробуй это:
источник
источник
Вы можете сгенерировать хеш MD5 для данного текста, используя методы из
MessageDigest
класса вjava.security
пакете. Ниже приведен фрагмент кода,Выходные данные функции MD5 представляют собой 128-битный хэш, представленный 32 шестнадцатеричными числами.
В случае, если вы используете базу данных, такую как MySQL, вы можете сделать это и более простым способом. Запрос
Select MD5(“text here”)
вернет MD5-хеш текста в скобках.источник
Вот для чего я пришел сюда - удобная функция scala, которая возвращает строку хеша MD5:
источник
Об этом есть статья на Codingkit. Проверить: http://codingkit.com/a/JAVA/2013/1020/2216.html
источник