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




Вам нужен java.security.MessageDigest.
Вызовите MessageDigest.getInstance("MD5"), чтобы получить MD5-экземпляр MessageDigest, который вы можете использовать.
Вычислить хэш, выполнив одно из следующих действий:
byte[] и вычислите хэш за одну операцию с md.digest(bytes).MessageDigest по одному фрагменту byte[] за раз, вызывая md.update(bytes). Когда вы закончите добавлять входные байты, вычислите хэш с помощью
md.digest().byte[], возвращаемый md.digest(), является хешем MD5.
Одна вещь, о которой здесь не упоминается, застала меня врасплох. Классы MessageDigest НЕ являются потокобезопасными. Если они будут использоваться разными потоками, просто создайте новый, вместо того, чтобы пытаться использовать их повторно.
Он использует несколько методов для изменения своего внутреннего состояния. Чем вообще может удивлять отсутствие безопасности потоков?
@Bombe: почему мы должны ожидать, что имеют узнает о внутреннем состоянии MessageDigest?
@DanBarowy хорошо, вы находятся мутируете его (то есть вызываете методы, которые не возвращают значения, но заставляют другие методы возвращать другие значения), поэтому, пока не будет доказано обратное, вы всегда должны предполагать, что это небезопасно для потоков.
@Traubenfuchs MessageDigest позволяет вводить данные по частям. Это было бы невозможно со статическим методом. Хотя вы можете утверждать, что им все равно следовало добавить один для удобства, когда вы можете передавать все данные сразу.
Имеет смысл. Я думаю, вы не всегда хотели бы перемещать байтовые массивы с несколькими гигабайтами! Тем не менее, просто позвольте ему взять поток.
@Traubenfuchs, и что он будет делать с байтами, прочитанными из этого потока, выбросить их?
Мне кажется, когда я писал это, я думал о "завершенном" и "готовом к употреблению" InputStream, который будет полностью истощен статическим методом. Любое необходимое состояние будет сохранено в теле метода.
Это не ответ на вопрос, это всего лишь пара ссылок. stackoverflow.com/help/how-to-answer
Класс 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-битный набор символов. Они не одинаковы.
(см. joelonsoftware.com/articles/Unicode.html для лучшего обоснования и объяснения)
а что, если мне нужна чистая строка?
@albanx: не существует такой вещи, как «чистая строка», если только вы не имели в виду сериализованное содержимое самого объекта Java. Пожалуйста, обратитесь к ранее размещенной ссылке на Joel On Software.
@DanielKamilKozar Мне нужна была шестнадцатеричная строка для сохранения в БД. dac2009 опубликовал решение для этого
Это было очень легко и просто, я бы порекомендовал это всем посетителям.
Тогда как преобразовать этот дайджест в строку, чтобы мы могли вставить его в mysql?
А еще лучше по возможности использовать yourString.getBytes(StandardCharsets.UTF_8). Это предотвращает обращение с UnsupportedEncodingException.
Ответ Bombe правильный, однако обратите внимание, что, если вы не должны использовать MD5 (например, принудительно для взаимодействия), лучшим выбором будет SHA1, поскольку MD5 имеет слабые места для длительного использования.
Добавлю, что SHA1 тоже имеет теоретические уязвимости, но не такие серьезные. Текущее состояние хеширования состоит в том, что существует ряд хэш-функций для замены кандидатов, но ни одна из них еще не стала стандартной передовой практикой для замены SHA1. Итак, в зависимости от ваших потребностей вам будет полезно сделать свой алгоритм хеширования настраиваемым, чтобы его можно было заменить в будущем.
Не могли бы вы указать мне на некоторые ресурсы, где я могу прочитать об относительных достоинствах и недостатках каждого из них?
Вероятно, лучшее, что вы можете сделать на данный момент, - это использовать SHA1 и быть готовым заменить его в будущем. Вы можете использовать более новые функции, но они еще не были предметом большого количества исследований. Вы можете отслеживать онлайн-ресурсы по безопасности, чтобы узнать, когда это изменится - например, блог Брюса Шнайера.
SHA1 является излишним, если вам не нужен криптографически безопасный хеш, т.е. вы не хотите, чтобы хеш помогал реконструировать исходное сообщение, и при этом вы не хотите, чтобы умный злоумышленник создал другое сообщение, которое соответствует хешу. Если оригинал не секрет и хэш не используется для безопасности, MD5 будет быстрым и простым. Например, Google Web Toolkit использует хеши MD5 в URL-адресах JavaScript (например, foo.js? Hash = 12345).
Вы также можете посмотреть класс DigestUtils проекта apache обычный кодек, который предоставляет очень удобные методы для создания дайджестов MD5 или SHA.
В частности, методы, которые возвращают «безопасные» закодированные представления байтовых данных в строковой форме.
Однако нет простого способа добавить класс DigestUtils в ваш проект без добавления тонны библиотек или переноса класса «на руку», для чего требуется как минимум еще два класса.
Не могу найти его и в репозиториях maven. Grrrr.
Должен быть в центральных репозиториях Maven, если я не схожу с ума: groupId = commons-codec artifactId = commons-codec version = 1.5
Взгляните на следующую ссылку, Пример получает 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, только конечные нули опущены,
Незначительная придирка: 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 между системами для одной и той же строки.
MD5 отлично подходит, если вам не нужна лучшая безопасность, и если вы делаете что-то вроде проверки целостности файла, тогда безопасность не рассматривается. В таком случае вы можете подумать о чем-то более простом и быстром, например, Adler32, который также поддерживается библиотеками Java.
Что заставляет вас думать, что целостность файла не является проблемой безопасности?
Вот как я его использую:
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 /…
Я бы заменил последнюю строчку на эту: String result = Hex.encodeHexString(resultByte);
Другая реализация: Быстрая реализация MD5 на Java
String hash = MD5.asHex(MD5.getHash(new File(filename)));
Это надежная автономная библиотека с минимальными зависимостями. Хорошая вещь.
Я нахожу это очень полезным. Для файла размером 4,57 ГБ потребовалось 15357 мс, тогда как для встроенной реализации Java потребовалось 19094 мс.
Это было очень полезно. У меня возникли проблемы с MessageDigest.getInstance ("MD5").
Нашел это:
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ŭloEbermann делает MessageDigest.getInstance ("MD5"); недостаточно? Я попытался добавить "MD5" в getBytes (), но он вернул ошибку
@BlazeTama "MD5" - это не кодировка, это алгоритм дайджеста сообщения (и не тот, который следует использовать в новых приложениях). Кодирование - это пара алгоритмов, которая преобразует байты в строки и строки в байты. Примером может быть «UTF-8», «US-ASCII», «ISO-8859-1», «UTF-16BE» и т.п. Используйте ту же кодировку, что и любая другая сторона, которая вычисляет хэш этой строки, иначе вы получите разные результаты.
Для примера набора символов ... (используйте UTF-8, который, на мой взгляд, является лучшим и наиболее совместимым) ... byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
Поскольку это не мое решение, и я сам не тестировал все сценарии, я оставлю его без изменений, хотя я думаю, что указание кодировки и т. д., Вероятно, является хорошей идеей.
Я только что скачал commons-codec.jar и получил отличный php, например md5. Вот руководство по эксплуатации.
Просто импортируйте его в свой проект и используйте
String Url = "your_url";
System.out.println( DigestUtils.md5Hex( Url ) );
и вот оно что.
Это метод, который обеспечивает то же возвращаемое значение, что и функция MySQL md5 (str). Многие другие ответы вернули другие значения.
Это не работает прямо на Android, потому что Android связывает общий кодек 1.2, для которого вам понадобится этот обходной путь: stackoverflow.com/a/9284092/2413303
Мой не очень показательный ответ:
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), чтобы иметь формат верхнего регистра
Нашел это решение, которое намного чище с точки зрения получения представления 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?
Приятно использовать BigInteger для получения шестнадцатеричного значения +1
Я только что узнал, что в некоторых случаях это генерирует только сумму MD5 длиной 31 символ, а не 32, как должно быть
@kovica это потому, что начальные нули обрезаются, если я правильно помню .. String.format("%032x", new BigInteger(1, hash)); Это должно решить эту проблему. «хэш» - это байт [] хеша.
В этом ответе есть ошибка с типом кодировки!
@HeshanPerera Почему вы упомянули в своем ответе «получение представления String из хеша MD5» !!? Но ваш код показывает логику преобразования String в хеш Md5. Если я не ошибаюсь, хеш MD5 - это односторонний алгоритм, и его нельзя преобразовать обратно в исходную строку.
Это кажется намного лучше. Вам даже не нужно фиксировать столько исключений.
Я сделал это ... Вроде работает нормально - я уверен, что кто-нибудь укажет на ошибки ...
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]));
}
}
Я не знаю, актуально ли это для всех, кто это читает, но у меня просто возникла проблема, которую я хотел
Я хотел сделать это только с классами 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. Я собираюсь отредактировать свое исходное решение, чтобы отразить то, что я только что узнал.
Также в Spring есть класс DigestUtils:
Этот класс содержит метод md5DigestAsHex(), который выполняет эту работу.
Кстати: производительность этого намного лучше, чем при использовании BigInteger для создания шестнадцатеричного строкового представления.
Как бы то ни было, я наткнулся на это, потому что хочу синтезировать идентификаторы 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 ())
Не нужно усложнять.
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();
@KurtAlfredKluever не забудьте вставить кодировку вроде 'Hashing.md5 (). HashString ("моя строка", Charsets.UTF_8) .asBytes ()'
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")));
Я видел только однострочник, который не использует внешнюю библиотеку.
Если я не ошибаюсь, это всегда возвращается в верхнем регистре, что не будет соответствовать md5, сделанному без использования шестнадцатеричного кода. Даже не совсем уверен, что это настоящий md5
@ walshie4 нет MD5 без шестнадцатеричного (см. ietf.org/rfc/rfc1321.txt), чтобы получить его в нижнем регистре, просто добавьте .toLower (). Сравните результаты с примерами, например, в en.wikipedia.org/wiki/MD5, тогда у вас будет больше шансов поверить в правильность кода библиотеки Javas.
У меня есть класс (хэш) для преобразования простого текста в хеш в форматах: 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");
}
}
<?php
echo 'MD5 :' . md5('Hello World') . "\n";
echo 'SHA1:' . sha1('Hello World') . "\n";
MD5 :b10a8db164e0754105b7a99be72e3fe5
SHA1:0a4d55a8d778e5022fab701977c5d840bbc486d0
public class HashTest {
@Test
public void test() {
String txt = "Hello World";
assertEquals("b10a8db164e0754105b7a99be72e3fe5", Hash.md5(txt));
assertEquals("0a4d55a8d778e5022fab701977c5d840bbc486d0", Hash.sha1(txt));
}
}
Как сказал @CedricSimon, это именно то, что я искал. Проголосовать за .. Спасибо!
попробуй это:
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 "";
}
}
Это, вероятно, худшее решение, так как оно удаляет ведущие нули.
Я считаю, что это наиболее четкий и краткий способ сделать это:
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(StandardCharsets.UTF_8.encode(string));
return String.format("%032x", new BigInteger(1, md5.digest()));
Отлично. Он не попадает в ловушку вырезания ведущих нулей.
Помните, что это не сработает для Android, если вы используете уровень API <19, но вам просто нужно изменить вторую строку с помощью md5.update (string.getBytes ("UTF-8")); Это добавит еще одно проверенное исключение для обработки, хотя ...
Я знаю, что вопрос касается 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!");
}
}
Добро пожаловать в Переполнение стека, вы можете прочитать как отправить ответ перед этим. Вкратце объясните, почему вы разместили этот код и для чего он нужен. Также подумайте о том, чтобы отформатировать свой ответ, чтобы читатели могли его легко понять.
это дает точный 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 выглядит как Scala
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();