Как я могу сгенерировать хеш MD5?

Есть ли какой-либо способ сгенерировать хеш MD5 строки в Java?

stackoverflow.com/questions/304268/…
Leif Gruenwoldt 08.09.2012 00:07

MD5 может быть небезопасным как односторонняя функция безопасности, но он по-прежнему хорош для общих приложений контрольной суммы.

rustyx 06.02.2015 18:57

вы можете попробовать на php, очень легко решается.

Anupam Haldkar 10.05.2020 23:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1 033
3
1 053 133
35
Перейти к ответу Данный вопрос помечен как решенный

Ответы 35

Ответ принят как подходящий

Вам нужен java.security.MessageDigest.

Вызовите MessageDigest.getInstance("MD5"), чтобы получить MD5-экземпляр MessageDigest, который вы можете использовать.

Вычислить хэш, выполнив одно из следующих действий:

  • Подайте весь ввод как byte[] и вычислите хэш за одну операцию с md.digest(bytes).
  • Подавать MessageDigest по одному фрагменту byte[] за раз, вызывая md.update(bytes). Когда вы закончите добавлять входные байты, вычислите хэш с помощью md.digest().

byte[], возвращаемый md.digest(), является хешем MD5.

Одна вещь, о которой здесь не упоминается, застала меня врасплох. Классы MessageDigest НЕ являются потокобезопасными. Если они будут использоваться разными потоками, просто создайте новый, вместо того, чтобы пытаться использовать их повторно.

mjuarez 07.03.2013 10:34

Он использует несколько методов для изменения своего внутреннего состояния. Чем вообще может удивлять отсутствие безопасности потоков?

Bombe 25.04.2013 11:57

@Bombe: почему мы должны ожидать, что имеют узнает о внутреннем состоянии MessageDigest?

Dan Barowy 01.07.2014 18:10

@DanBarowy хорошо, вы находятся мутируете его (то есть вызываете методы, которые не возвращают значения, но заставляют другие методы возвращать другие значения), поэтому, пока не будет доказано обратное, вы всегда должны предполагать, что это небезопасно для потоков.

Bombe 09.07.2014 22:17

@Traubenfuchs MessageDigest позволяет вводить данные по частям. Это было бы невозможно со статическим методом. Хотя вы можете утверждать, что им все равно следовало добавить один для удобства, когда вы можете передавать все данные сразу.

user253751 16.08.2015 15:39

Имеет смысл. Я думаю, вы не всегда хотели бы перемещать байтовые массивы с несколькими гигабайтами! Тем не менее, просто позвольте ему взять поток.

Traubenfuchs 17.08.2015 12:42

@Traubenfuchs, и что он будет делать с байтами, прочитанными из этого потока, выбросить их?

kbolino 28.05.2016 06:00

Мне кажется, когда я писал это, я думал о "завершенном" и "готовом к употреблению" InputStream, который будет полностью истощен статическим методом. Любое необходимое состояние будет сохранено в теле метода.

Traubenfuchs 28.05.2016 12:05

Это не ответ на вопрос, это всего лишь пара ссылок. stackoverflow.com/help/how-to-answer

Fran Marzoa 20.02.2018 23:13

Класс MessageDigest может предоставить вам экземпляр дайджеста MD5.

При работе со строками и криптографическими классами убедитесь, что всегда указывает кодировку, в которой вы хотите байтовое представление. Если вы просто используете string.getBytes(), он будет использовать платформу по умолчанию. (Не все платформы используют одни и те же значения по умолчанию)

import java.security.*;

..

byte[] bytesOfMessage = yourString.getBytes("UTF-8");

MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);

Если у вас много данных, обратите внимание на метод .update(byte[]), который можно вызывать повторно. Затем вызовите .digest(), чтобы получить результирующий хэш.

«LATIN1»! = «ASCII» (или «US-ASCII»). ASCII - это 7-битный набор символов, Latin1 - 8-битный набор символов. Они не одинаковы.

Bombe 07.01.2009 10:57

(см. joelonsoftware.com/articles/Unicode.html для лучшего обоснования и объяснения)

Piskvor left the building 07.01.2009 22:57
Эта тема также полезен, если вам нужно преобразовать полученные байты в шестнадцатеричную строку.
weekens 22.05.2012 11:25

а что, если мне нужна чистая строка?

albanx 05.11.2015 02:09

@albanx: не существует такой вещи, как «чистая строка», если только вы не имели в виду сериализованное содержимое самого объекта Java. Пожалуйста, обратитесь к ранее размещенной ссылке на Joel On Software.

Daniel Kamil Kozar 21.02.2016 02:29

@DanielKamilKozar Мне нужна была шестнадцатеричная строка для сохранения в БД. dac2009 опубликовал решение для этого

albanx 21.02.2016 02:41

Это было очень легко и просто, я бы порекомендовал это всем посетителям.

Humphrey 03.11.2017 15:49

Тогда как преобразовать этот дайджест в строку, чтобы мы могли вставить его в mysql?

Humphrey 08.11.2017 11:39

А еще лучше по возможности использовать yourString.getBytes(StandardCharsets.UTF_8). Это предотвращает обращение с UnsupportedEncodingException.

Hummeling Engineering BV 07.03.2019 13:28

Ответ Bombe правильный, однако обратите внимание, что, если вы не должны использовать MD5 (например, принудительно для взаимодействия), лучшим выбором будет SHA1, поскольку MD5 имеет слабые места для длительного использования.

Добавлю, что SHA1 тоже имеет теоретические уязвимости, но не такие серьезные. Текущее состояние хеширования состоит в том, что существует ряд хэш-функций для замены кандидатов, но ни одна из них еще не стала стандартной передовой практикой для замены SHA1. Итак, в зависимости от ваших потребностей вам будет полезно сделать свой алгоритм хеширования настраиваемым, чтобы его можно было заменить в будущем.

Не могли бы вы указать мне на некоторые ресурсы, где я могу прочитать об относительных достоинствах и недостатках каждого из них?

Akshay 06.01.2009 13:19

Вероятно, лучшее, что вы можете сделать на данный момент, - это использовать SHA1 и быть готовым заменить его в будущем. Вы можете использовать более новые функции, но они еще не были предметом большого количества исследований. Вы можете отслеживать онлайн-ресурсы по безопасности, чтобы узнать, когда это изменится - например, блог Брюса Шнайера.

frankodwyer 06.01.2009 13:49

SHA1 является излишним, если вам не нужен криптографически безопасный хеш, т.е. вы не хотите, чтобы хеш помогал реконструировать исходное сообщение, и при этом вы не хотите, чтобы умный злоумышленник создал другое сообщение, которое соответствует хешу. Если оригинал не секрет и хэш не используется для безопасности, MD5 будет быстрым и простым. Например, Google Web Toolkit использует хеши MD5 в URL-адресах JavaScript (например, foo.js? Hash = 12345).

David Leppik 19.04.2011 19:14

Вы также можете посмотреть класс DigestUtils проекта apache обычный кодек, который предоставляет очень удобные методы для создания дайджестов MD5 или SHA.

В частности, методы, которые возвращают «безопасные» закодированные представления байтовых данных в строковой форме.

Rob 07.01.2009 22:21

Однако нет простого способа добавить класс DigestUtils в ваш проект без добавления тонны библиотек или переноса класса «на руку», для чего требуется как минимум еще два класса.

iuiz 24.07.2011 00:52

Не могу найти его и в репозиториях maven. Grrrr.

sparkyspider 04.10.2011 20:05

Должен быть в центральных репозиториях Maven, если я не схожу с ума: groupId = commons-codec artifactId = commons-codec version = 1.5

Nick Spacek 12.10.2011 21:10

Взгляните на следующую ссылку, Пример получает MD5-хэш предоставленного изображения: MD5-хэш изображения

Если вы действительно хотите получить ответ в виде строки, а не массива байтов, вы всегда можете сделать что-то вроде этого:

String plaintext = "your text here";
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
BigInteger bigInt = new BigInteger(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 30.08.2010 02:29

Незначительная придирка: m.reset () не требуется сразу после вызова getInstance. Более мелкие: «ваш текст здесь» требует двойных кавычек.

David Leppik 19.04.2011 19:28

Начиная с Java 11, вы можете использовать hashtext = "0".repeat(32 - hashtext.length()) + hashtext вместо while, поэтому редакторы не будут предупреждать вас о том, что вы выполняете конкатенацию строк внутри цикла.

tom 14.05.2019 16:29

Вместо m.update (plaintext.getBytes ()); Я бы рекомендовал указать кодировку. например m.update (plaintext.getBytes ("UTF-8")); getBytes () не гарантирует кодировку и может отличаться от системы к системе, что может привести к разным результатам MD5 между системами для одной и той же строки.

user1819780 27.03.2020 08:35

MD5 отлично подходит, если вам не нужна лучшая безопасность, и если вы делаете что-то вроде проверки целостности файла, тогда безопасность не рассматривается. В таком случае вы можете подумать о чем-то более простом и быстром, например, Adler32, который также поддерживается библиотеками Java.

Что заставляет вас думать, что целостность файла не является проблемой безопасности?

Jeremy Huiskamp 13.10.2011 04:44

Вот как я его использую:

final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(string.getBytes(Charset.forName("UTF8")));
final byte[] resultByte = messageDigest.digest();
final String result = new String(Hex.encodeHex(resultByte));

где Hex: org.apache.commons.codec.binary.Hex из Проект Apache Commons.

Если вы все равно используете кодек Apache Commons, вы можете использовать: commons.apache.org/codec/api-release/org/apache/commons/code‌ c /…

squiddle 25.10.2010 19:10

Я бы заменил последнюю строчку на эту: String result = Hex.encodeHexString(resultByte);

bluish 24.05.2011 13:35

Другая реализация: Быстрая реализация MD5 на Java

String hash = MD5.asHex(MD5.getHash(new File(filename)));

Это надежная автономная библиотека с минимальными зависимостями. Хорошая вещь.

Ajax 22.03.2014 12:54

Я нахожу это очень полезным. Для файла размером 4,57 ГБ потребовалось 15357 мс, тогда как для встроенной реализации Java потребовалось 19094 мс.

bkrish 02.05.2016 01:37

Это было очень полезно. У меня возникли проблемы с MessageDigest.getInstance ("MD5").

arun 19.09.2020 22:53

Нашел это:

public String MD5(String md5) {
   try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(md5.getBytes());
        StringBuffer sb = new StringBuffer();
        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) {
    }
    return null;
}

на сайте ниже я не беру на себя ответственность за это, но это решение, которое работает! Для меня много другого кода не работало должным образом, я пропустил нули в хэше. Кажется, это то же самое, что и в PHP. источник: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093

Вы должны указать кодировку, которая будет использоваться в getBytes(), иначе ваш код будет иметь разные результаты на разных платформах / пользовательских настройках.

Paŭlo Ebermann 04.07.2011 01:57

@ PaŭloEbermann делает MessageDigest.getInstance ("MD5"); недостаточно? Я попытался добавить "MD5" в getBytes (), но он вернул ошибку

Blaze Tama 19.02.2014 09:29

@BlazeTama "MD5" - это не кодировка, это алгоритм дайджеста сообщения (и не тот, который следует использовать в новых приложениях). Кодирование - это пара алгоритмов, которая преобразует байты в строки и строки в байты. Примером может быть «UTF-8», «US-ASCII», «ISO-8859-1», «UTF-16BE» и т.п. Используйте ту же кодировку, что и любая другая сторона, которая вычисляет хэш этой строки, иначе вы получите разные результаты.

Paŭlo Ebermann 21.02.2014 23:48

Для примера набора символов ... (используйте UTF-8, который, на мой взгляд, является лучшим и наиболее совместимым) ... byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));

Richard 25.11.2014 04:56

Поскольку это не мое решение, и я сам не тестировал все сценарии, я оставлю его без изменений, хотя я думаю, что указание кодировки и т. д., Вероятно, является хорошей идеей.

dac2009 08.07.2019 13:45

Я только что скачал commons-codec.jar и получил отличный php, например md5. Вот руководство по эксплуатации.

Просто импортируйте его в свой проект и используйте

String Url = "your_url";

System.out.println( DigestUtils.md5Hex( Url ) );

и вот оно что.

Это метод, который обеспечивает то же возвращаемое значение, что и функция MySQL md5 (str). Многие другие ответы вернули другие значения.

rwitzel 18.03.2015 17:54

Это не работает прямо на Android, потому что Android связывает общий кодек 1.2, для которого вам понадобится этот обходной путь: stackoverflow.com/a/9284092/2413303

EpicPandaForce 19.03.2015 13:22

Мой не очень показательный ответ:

private String md5(String s) {
    try {
        MessageDigest m = MessageDigest.getInstance("MD5");
        m.update(s.getBytes(), 0, s.length());
        BigInteger i = new BigInteger(1,m.digest());
        return String.format("%1$032x", i);         
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

и String.format("%1$032X", big), чтобы иметь формат верхнего регистра

alex 23.05.2014 19:10

Нашел это решение, которое намного чище с точки зрения получения представления String из хеша MD5.

import java.security.*;
import java.math.*;

public class MD5 {
    public static void main(String args[]) throws Exception{
        String s = "This is a test";
        MessageDigest m=MessageDigest.getInstance("MD5");
        m.update(s.getBytes(),0,s.length());
        System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));
    }
}

Код был извлечен из здесь.

Почему у этого ответа -1, а у другого, более короткого и менее информативного ответа +146?

Nilzor 12.02.2013 16:17

Приятно использовать BigInteger для получения шестнадцатеричного значения +1

Dave.B 14.03.2013 21:42

Я только что узнал, что в некоторых случаях это генерирует только сумму MD5 длиной 31 символ, а не 32, как должно быть

kovica 29.03.2013 18:09

@kovica это потому, что начальные нули обрезаются, если я правильно помню .. String.format("%032x", new BigInteger(1, hash)); Это должно решить эту проблему. «хэш» - это байт [] хеша.

Heshan Perera 01.04.2013 09:10

В этом ответе есть ошибка с типом кодировки!

Dawid Drozd 13.04.2015 13:24

@HeshanPerera Почему вы упомянули в своем ответе «получение представления String из хеша MD5» !!? Но ваш код показывает логику преобразования String в хеш Md5. Если я не ошибаюсь, хеш MD5 - это односторонний алгоритм, и его нельзя преобразовать обратно в исходную строку.

supernova 17.09.2015 18:39

Это кажется намного лучше. Вам даже не нужно фиксировать столько исключений.

JGFMK 03.01.2020 01:30

Я сделал это ... Вроде работает нормально - я уверен, что кто-нибудь укажет на ошибки ...

public final class MD5 {
public enum SaltOption {
    BEFORE, AFTER, BOTH, NONE;
}
private static final String ALG = "MD5";
//For conversion to 2-char hex
private static final char[] digits = {
    '0' , '1' , '2' , '3' , '4' , '5' ,
    '6' , '7' , '8' , '9' , 'a' , 'b' ,
    'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
    'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
    'o' , 'p' , 'q' , 'r' , 's' , 't' ,
    'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};

private SaltOption opt;

/**
 * Added the SaltOption constructor since everybody
 * has their own standards when it comes to salting
 * hashes.
 * 
 * This gives the developer the option...
 * 
 * @param option The salt option to use, BEFORE, AFTER, BOTH or NONE.
 */
public MD5(final SaltOption option) {
    //TODO: Add Char Encoding options too... I was too lazy!
    this.opt = option;
}

/**
 * 
 * Returns the salted MD5 checksum of the text passed in as an argument.
 * 
 * If the salt is an empty byte array - no salt is applied.
 * 
 * @param txt The text to run through the MD5 algorithm.
 * @param salt The salt value in bytes.
 * @return The salted MD5 checksum as a <code>byte[]</code>
 * @throws NoSuchAlgorithmException
 */
private byte[] createChecksum(final String txt, final byte[] salt) throws NoSuchAlgorithmException {
    final MessageDigest complete = MessageDigest.getInstance(ALG);
    if (opt.equals(SaltOption.BEFORE) || opt.equals(SaltOption.BOTH)) {
        complete.update(salt);
    }
    complete.update(txt.getBytes());
    if (opt.equals(SaltOption.AFTER) || opt.equals(SaltOption.BOTH)) {
        complete.update(salt);
    }
    return complete.digest();
}

/**
 * 
 * Returns the salted MD5 checksum of the file passed in as an argument.
 * 
 * If the salt is an empty byte array - no salt is applied.
 * 
 * @param fle The file to run through the MD5 algorithm.
 * @param salt The salt value in bytes.
 * @return The salted MD5 checksum as a <code>byte[]</code>
 * @throws IOException
 * @throws NoSuchAlgorithmException
 */
private byte[] createChecksum(final File fle, final byte[] salt)
        throws IOException, NoSuchAlgorithmException {
    final byte[] buffer = new byte[1024];
    final MessageDigest complete = MessageDigest.getInstance(ALG);
            if (opt.equals(SaltOption.BEFORE) || opt.equals(SaltOption.BOTH)) {
            complete.update(salt);
        }
    int numRead;
    InputStream fis = null;
    try {
        fis = new FileInputStream(fle);
        do {
            numRead = fis.read(buffer);
            if (numRead > 0) {
                complete.update(buffer, 0, numRead);
            }
        } while (numRead != -1);
    } finally {
    if (fis != null) {
            fis.close();
        }
    }
            if (opt.equals(SaltOption.AFTER) || opt.equals(SaltOption.BOTH)) {
            complete.update(salt);
        }
    return complete.digest();
}

/**
 * 
 * Efficiently converts a byte array to its 2 char per byte hex equivalent.
 * 
 * This was adapted from JDK code in the Integer class, I just didn't like
 * having to use substrings once I got the result...
 *
 * @param b The byte array to convert
 * @return The converted String, 2 chars per byte...
 */
private String convertToHex(final byte[] b) {
    int x;
    int charPos;
    int radix;
    int mask;
    final char[] buf = new char[32];
    final char[] tmp = new char[3];
    final StringBuilder md5 = new StringBuilder();
    for (int i = 0; i < b.length; i++) {
        x = (b[i] & 0xFF) | 0x100;
        charPos = 32;
        radix = 1 << 4;
        mask = radix - 1;
        do {
            buf[--charPos] = digits[x & mask];
            x >>>= 4;
        } while (x != 0);
        System.arraycopy(buf, charPos, tmp, 0, (32 - charPos));
        md5.append(Arrays.copyOfRange(tmp, 1, 3));
    }
    return md5.toString();
}

/**
 * 
 * Returns the salted MD5 checksum of the file passed in as an argument.
 * 
 * @param fle The file you want want to run through the MD5 algorithm.
 * @param salt The salt value in bytes
 * @return The salted MD5 checksum as a 2 char per byte HEX <code>String</code>
 * @throws NoSuchAlgorithmException
 * @throws IOException
 */
public String getMD5Checksum(final File fle, final byte[] salt)
        throws NoSuchAlgorithmException, IOException {
    return convertToHex(createChecksum(fle, salt));
}

/**
 * 
 * Returns the MD5 checksum of the file passed in as an argument.
 * 
 * @param fle The file you want want to run through the MD5 algorithm.
 * @return The MD5 checksum as a 2 char per byte HEX <code>String</code>
 * @throws NoSuchAlgorithmException
 * @throws IOException
 */
public String getMD5Checksum(final File fle)
        throws NoSuchAlgorithmException, IOException {
    return convertToHex(createChecksum(fle, new byte[0]));
}

/**
 * 
 * Returns the salted MD5 checksum of the text passed in as an argument.
 * 
 * @param txt The text you want want to run through the MD5 algorithm.
 * @param salt The salt value in bytes.
 * @return The salted MD5 checksum as a 2 char per byte HEX <code>String</code>
 * @throws NoSuchAlgorithmException
 * @throws IOException
 */
public String getMD5Checksum(final String txt, final byte[] salt)
        throws NoSuchAlgorithmException {
    return convertToHex(createChecksum(txt, salt));
}

/**
 * 
 * Returns the MD5 checksum of the text passed in as an argument.
 * 
 * @param txt The text you want want to run through the MD5 algorithm.
 * @return The MD5 checksum as a 2 char per byte HEX <code>String</code>
 * @throws NoSuchAlgorithmException
 * @throws IOException
 */
public String getMD5Checksum(final String txt)
        throws NoSuchAlgorithmException {

    return convertToHex(createChecksum(txt, new byte[0]));
}
}

Я не знаю, актуально ли это для всех, кто это читает, но у меня просто возникла проблема, которую я хотел

  • скачать файл с заданного URL а также
  • сравните его MD5 с известным значением.

Я хотел сделать это только с классами JRE (без Apache Commons или подобных). Быстрый поиск в Интернете не показал мне фрагментов кода, выполняющих оба одновременно, только каждую задачу отдельно. Поскольку для этого требуется дважды прочитать один и тот же файл, я подумал, что, возможно, стоит написать код, который объединяет обе задачи, вычисляя контрольную сумму на лету при загрузке файла. Это мой результат (извините, если это не идеальная Java, но я думаю, вы все равно поняли идею):

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.security.DigestOutputStream;        // new
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

void downloadFile(String fromURL, String toFile, BigInteger md5)
    throws IOException, NoSuchAlgorithmException
{
    ReadableByteChannel in = Channels.newChannel(new URL(fromURL).openStream());
    MessageDigest md5Digest = MessageDigest.getInstance("MD5");
    WritableByteChannel out = Channels.newChannel(
        //new FileOutputStream(toFile));  // old
        new DigestOutputStream(new FileOutputStream(toFile), md5Digest));  // new
    ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);  // 1 MB

    while (in.read(buffer) != -1) {
        buffer.flip();
        //md5Digest.update(buffer.asReadOnlyBuffer());  // old
        out.write(buffer);
        buffer.clear();
    }

    BigInteger md5Actual = new BigInteger(1, md5Digest.digest()); 
    if (! md5Actual.equals(md5))
        throw new RuntimeException(
            "MD5 mismatch for file " + toFile +
            ": expected " + md5.toString(16) +
            ", got " + md5Actual.toString(16)
        );
}

О, кстати, прежде чем кто-либо, кроме меня, заметит, насколько плохо я знаю JRE: я только что открыл для себя DigestInputStream и DigestOutputStream. Я собираюсь отредактировать свое исходное решение, чтобы отразить то, что я только что узнал.

kriegaex 26.06.2012 12:45

Также в Spring есть класс DigestUtils:

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/DigestUtils.html

Этот класс содержит метод md5DigestAsHex(), который выполняет эту работу.

Кстати: производительность этого намного лучше, чем при использовании BigInteger для создания шестнадцатеричного строкового представления.

James 17.04.2018 12:37

Как бы то ни было, я наткнулся на это, потому что хочу синтезировать идентификаторы GUID из естественного ключа для программы, которая будет устанавливать компоненты COM; Я хочу синхронизировать, чтобы не управлять жизненным циклом GUID. Я использую MD5, а затем использую класс UUID, чтобы получить из него строку. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439 вызывает эту проблему).

В любом случае java.util.UUID может дать вам красивую строку из байтов MD5.

return UUID.nameUUIDFromBytes(md5Bytes).toString();

фактически он принимает не только массив байтов MD5 (размер == 16). Вы можете передавать байтовый массив любой длины. Он будет преобразован в массив байтов MD5 с помощью MD5 MessageDigest (см. исходный код nameUUIDFromBytes ())

Lu55 21.10.2017 01:18

Не нужно усложнять. DigestUtils отлично работает и позволяет комфортно работать с хешами md5.

DigestUtils.md5Hex(_hash);

или же

DigestUtils.md5(_hash);

Либо вы можете использовать любые другие методы шифрования, такие как sha или md.

Другой вариант - использовать Методы хеширования гуавы:

Hasher hasher = Hashing.md5().newHasher();
hasher.putString("my string");
byte[] md5 = hasher.hash().asBytes();

Удобно, если вы уже используете Guava (что, если вы этого не сделаете, вам, вероятно, следует).

или используя один из методов быстрого доступа: Hashing.md5().hashString("my string").asBytes();

Kurt Alfred Kluever 17.11.2015 19:23

@KurtAlfredKluever не забудьте вставить кодировку вроде 'Hashing.md5 (). HashString ("моя строка", Charsets.UTF_8) .asBytes ()'

Justin 21.04.2016 17:14
 import java.math.BigInteger;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;

/**
* MD5 encryption
*
* @author Hongten
*
*/
public class MD5 {

 public static void main(String[] args) {
     System.out.println(MD5.getMD5("123456"));
 }

 /**
  * Use md5 encoded code value
  *
  * @param sInput
  * clearly
  * @ return md5 encrypted password
  */
 public static String getMD5(String sInput) {

     String algorithm = "";
     if (sInput == null) {
         return "null";
     }
     try {
         algorithm = System.getProperty("MD5.algorithm", "MD5");
     } catch (SecurityException se) {
     }
     MessageDigest md = null;
     try {
         md = MessageDigest.getInstance(algorithm);
     } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
     }
     byte buffer[] = sInput.getBytes();

     for (int count = 0; count < sInput.length(); count++) {
         md.update(buffer, 0, count);
     }
     byte bDigest[] = md.digest();
     BigInteger bi = new BigInteger(bDigest);
     return (bi.toString(16));
 }
}

Об этом есть статья на Codingkit. Выезд: http://codingkit.com/a/JAVA/2013/1020/2216.html

Вы можете попробовать следующее. Подробную информацию и коды загрузки можно найти здесь: http://jkssweetlife.com/java-hashgenerator-md5-sha-1/

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Example {

public static void main(String[] args) throws Exception {

    final String inputString = "Hello MD5";

    System.out.println("MD5 hex for '" + inputString + "' :");
    System.out.println(getMD5Hex(inputString));
}

public static String getMD5Hex(final String inputString) throws NoSuchAlgorithmException {

    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(inputString.getBytes());

    byte[] digest = md.digest();

    return convertByteToHex(digest);
}

private static String convertByteToHex(byte[] byteData) {

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < byteData.length; i++) {
        sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString();
}
}

Другая реализация:

import javax.xml.bind.DatatypeConverter;

String hash = DatatypeConverter.printHexBinary( 
           MessageDigest.getInstance("MD5").digest("SOMESTRING".getBytes("UTF-8")));

Я видел только однострочник, который не использует внешнюю библиотеку.

holmis83 07.02.2017 12:33

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

walshie4 29.06.2017 05:00

@ walshie4 нет MD5 без шестнадцатеричного (см. ietf.org/rfc/rfc1321.txt), чтобы получить его в нижнем регистре, просто добавьте .toLower (). Сравните результаты с примерами, например, в en.wikipedia.org/wiki/MD5, тогда у вас будет больше шансов поверить в правильность кода библиотеки Javas.

stacker 29.06.2017 11:27

У меня есть класс (хэш) для преобразования простого текста в хеш в форматах: md5 или sha1, аналогично функциям php (мкр5, sha1):

public class Hash {
    /**
     * 
     * @param txt, text in plain format
     * @param hashType MD5 OR SHA1
     * @return hash in hashType 
     */
    public static String getHash(String txt, String hashType) {
        try {
                    java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);
                    byte[] array = md.digest(txt.getBytes());
                    StringBuffer sb = new StringBuffer();
                    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
            }
            return null;
    }

    public static String md5(String txt) {
        return Hash.getHash(txt, "MD5");
    }

    public static String sha1(String txt) {
        return Hash.getHash(txt, "SHA1");
    }
}

Тестирование с JUnit и PHP

Скрипт PHP:

<?php

echo 'MD5 :' . md5('Hello World') . "\n";
echo 'SHA1:' . sha1('Hello World') . "\n";

Вывод PHP-скрипта:

MD5 :b10a8db164e0754105b7a99be72e3fe5
SHA1:0a4d55a8d778e5022fab701977c5d840bbc486d0

Используя пример и тестирование с JUnit:

    public class HashTest {

    @Test
    public void test() {
        String txt = "Hello World";
        assertEquals("b10a8db164e0754105b7a99be72e3fe5", Hash.md5(txt));
        assertEquals("0a4d55a8d778e5022fab701977c5d840bbc486d0", Hash.sha1(txt));
    }

}

Код в GitHub

https://github.com/fitorec/java-hashes

Как сказал @CedricSimon, это именно то, что я искал. Проголосовать за .. Спасибо!

Joabe Lucena 02.12.2016 19:11

попробуй это:

public static String getHashMD5(String string) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        BigInteger bi = new BigInteger(1, md.digest(string.getBytes()));
        return bi.toString(16);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(MD5Utils.class
                .getName()).log(Level.SEVERE, null, ex);

        return "";
    }
}

Это, вероятно, худшее решение, так как оно удаляет ведущие нули.

Jannick 13.08.2015 16:02

Я считаю, что это наиболее четкий и краткий способ сделать это:

MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(StandardCharsets.UTF_8.encode(string));
return String.format("%032x", new BigInteger(1, md5.digest()));

Отлично. Он не попадает в ловушку вырезания ведущих нулей.

Markus Pscheidt 10.06.2016 10:29

Помните, что это не сработает для Android, если вы используете уровень API <19, но вам просто нужно изменить вторую строку с помощью md5.update (string.getBytes ("UTF-8")); Это добавит еще одно проверенное исключение для обработки, хотя ...

Fran Marzoa 20.02.2018 23:27

Я знаю, что вопрос касается Java, но я хотел бы перечислить здесь ActionScript 1 исходный код (здесь лицензия) до сгенерировать MD5 другим способом, чем ответы, перечисленные на этой странице.

Приведенная ниже функция работает хорошо и, несомненно, может быть преобразована в Java:

/* MD5 implementation from http://www.webtoolkit.info */

function md5(string) {

    function RotateLeft(lValue, iShiftBits) {
        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
    }

    function AddUnsigned(lX,lY) {
        var lX4,lY4,lX8,lY8,lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
        if (lX4 & lY4) {
            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        }
        if (lX4 | lY4) {
            if (lResult & 0x40000000) {
                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            } else {
                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
            }
        } else {
            return (lResult ^ lX8 ^ lY8);
        }
    }

    function F(x,y,z) { return (x & y) | ((~x) & z); }
    function G(x,y,z) { return (x & z) | (y & (~z)); }
    function H(x,y,z) { return (x ^ y ^ z); }
    function I(x,y,z) { return (y ^ (x | (~z))); }

    function FF(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function GG(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function HH(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function II(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };

    function ConvertToWordArray(string) {
        var lWordCount;
        var lMessageLength = string.length;
        var lNumberOfWords_temp1=lMessageLength + 8;
        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
        var lWordArray=Array(lNumberOfWords-1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while ( lByteCount < lMessageLength ) {
            lWordCount = (lByteCount-(lByteCount % 4))/4;
            lBytePosition = (lByteCount % 4)*8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | 
                (string.charCodeAt(lByteCount)<<lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount-(lByteCount % 4))/4;
        lBytePosition = (lByteCount % 4)*8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
        return lWordArray;
    };

    function WordToHex(lValue) {
        var WordToHexValue = "",WordToHexValue_temp = "",lByte,lCount;
        for (lCount = 0;lCount<=3;lCount++) {
            lByte = (lValue>>>(lCount*8)) & 255;
            WordToHexValue_temp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + 
                WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
        }
        return WordToHexValue;
    };

    function Utf8Encode(string) {

        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if ((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    };

    var x=Array();
    var k,AA,BB,CC,DD,a,b,c,d;
    var S11=7, S12=12, S13=17, S14=22;
    var S21=5, S22=9 , S23=14, S24=20;
    var S31=4, S32=11, S33=16, S34=23;
    var S41=6, S42=10, S43=15, S44=21;

    string = Utf8Encode(string);

    x = ConvertToWordArray(string);

    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

    for (k=0;k<x.length;k+=16) {
        AA=a; BB=b; CC=c; DD=d;
        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
        d=GG(d,a,b,c,x[k+10],S22,0x2441453);
        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
        a=II(a,b,c,d,x[k+0], S41,0xF4292244);
        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
        c=II(c,d,a,b,x[k+6], S43,0xA3014314);
        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
        a=AddUnsigned(a,AA);
        b=AddUnsigned(b,BB);
        c=AddUnsigned(c,CC);
        d=AddUnsigned(d,DD);
    }

    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);

    return temp.toLowerCase();
}

Я пришел сюда ради удобной функции scala, которая возвращает строку хэша MD5:

def md5(text: String) : String = java.security.MessageDigest.getInstance("MD5").digest(text.getBytes()).map(0xFF & _).map { "%02x".format(_) }.foldLeft(""){_ + _}

В отличие от PHP, где вы можете выполнить хеширование вашего текста MD5, просто вызвав функцию md5, то есть md5($text), в Java это было немного усложнено. Я обычно реализовывал это, вызывая функцию, которая возвращает хеш-текст md5. Вот как я это реализовал. Сначала создайте функцию с именем md5hashing внутри вашего основного класса, как показано ниже.

public static String 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 = new BigInteger(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 exception
            JOptionPane.showMessageDialog(null,e1.getClass().getName() + ": " + e1.getMessage());   
        }
        return hashtext;     
    }

Теперь вызывайте функцию всякий раз, когда вам нужно, как указано ниже.

String text = textFieldName.getText();
String pass = md5hashing(text);

Здесь вы можете видеть, что к хэш-тексту добавлен ноль, чтобы он соответствовал хешированию md5 в PHP.

private String hashuj(String dane) throws ServletException{
    try {
        MessageDigest m = MessageDigest.getInstance("MD5");
        byte[] bufor = dane.getBytes();
        m.update(bufor,0,bufor.length);
        BigInteger hash = new BigInteger(1,m.dige`enter code here`st());
        return String.format("%1$032X", hash);

    } catch (NoSuchAlgorithmException nsae) {
        throw new ServletException("Algorytm szyfrowania nie jest obsługiwany!");
    }
}

Добро пожаловать в Переполнение стека, вы можете прочитать как отправить ответ перед этим. Вкратце объясните, почему вы разместили этот код и для чего он нужен. Также подумайте о том, чтобы отформатировать свой ответ, чтобы читатели могли его легко понять.

Nacho 11.04.2016 20:37

это дает точный md5, как вы получаете из функции mysql md5 или функций php md5 и т. д. Это тот, который я использую (вы можете изменить в соответствии с вашими потребностями)

public static String md5( String input ) {
    try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(input.getBytes( "UTF-8" ));
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; i++) {
            sb.append( String.format( "%02x", array[i]));
        }
        return sb.toString();
    } catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
        return null;            
    }

}
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)

Это язык Котлин?

Isuru 18.06.2017 20:08

@Isuru выглядит как Scala

gildor 03.10.2017 04:31
import java.security.*;
import javax.xml.bind.*;

byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytesOfDigest = md.digest(bytesOfMessage);
String digest = DatatypeConverter.printHexBinary(bytesOfDigest).toLowerCase();

Вы можете сгенерировать хеш MD5 для данного текста, используя методы класса MessageDigest в пакете java.security. Ниже приведен полный фрагмент кода,

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;

public class MD5HashGenerator 
{

   public static void main(String args[]) throws NoSuchAlgorithmException
   {
       String stringToHash = "MyJavaCode"; 
       MessageDigest messageDigest = MessageDigest.getInstance("MD5");
       messageDigest.update(stringToHash.getBytes());
       byte[] digiest = messageDigest.digest();
       String hashedOutput = DatatypeConverter.printHexBinary(digiest);
       System.out.println(hashedOutput);
   }
}

Результатом функции MD5 является 128-битный хэш, представленный 32 шестнадцатеричными числами.

В случае, если вы используете такую ​​базу данных, как MySQL, вы можете сделать это и более простым способом. Запрос Select MD5(“text here”) вернет хеш MD5 текста в скобках.

Я сделал это с помощью php следующим образом

<?php
$goodtext = "Not found";
// If there is no parameter, this code is all skipped
if ( isset($_GET['md5']) ) {
    $time_pre = microtime(true);
    $md5 = $_GET['md5'];
    // This is our alphabet
    $txt = "0123456789";
    $show = 15;
    // Outer loop go go through the alphabet for the
    // first position in our "possible" pre-hash
    // text
    for($i=0; $i<strlen($txt); $i++ ) {
        $ch1 = $txt[$i];   // The first of two characters
        // Our inner loop Note the use of new variables
        // $j and $ch2 
        for($j=0; $j<strlen($txt); $j++ ) {
            $ch2 = $txt[$j];  // Our second character
            for($k=0; $k<strlen($txt); $k++ ) {
                $ch3 = $txt[$k];
                for($l=0; $l<strlen($txt); $l++){
                    $ch4 = $txt[$l];
                    // Concatenate the two characters together to 
                    // form the "possible" pre-hash text
                    $try = $ch1.$ch2.$ch3.$ch4;
                    // Run the hash and then check to see if we match
                    $check = hash('md5', $try);
                    if ( $check == $md5 ) {
                        $goodtext = $try;
                        break;   // Exit the inner loop
                    }
                    // Debug output until $show hits 0
                    if ( $show > 0 ) {
                        print "$check $try\n";
                        $show = $show - 1;
                    }
                    if ($goodtext == $try){
                        break;
                    }
                }
                if ($goodtext == $try){
                    break;
                }
            }
            if ($goodtext == $try) {
                break;  
            }
        }
        if ($goodtext == $try){
            break;
        }
    }
    // Compute ellapsed time
    $time_post = microtime(true);
    print "Ellapsed time: ";
    print $time_post-$time_pre;
    print "\n";
}
?>

вы можете сослаться на это - источник

Вы можете попробовать использовать Цезарь.

Первый вариант:

byte[] hash =
    new Hash(
        new ImmutableMessageDigest(
            MessageDigest.getInstance("MD5")
        ),
        new PlainText("String to hash...")
    ).asArray();

Второй вариант:

byte[] hash =
    new ImmutableMessageDigest(
        MessageDigest.getInstance("MD5")
    ).update(
        new PlainText("String to hash...")
    ).digest();

Другие вопросы по теме