在Java中是否有任何方法可以生成一个字符串的MD5哈希?


当前回答

MessageDigest类可以为您提供MD5摘要的实例。

当使用字符串和加密类时,请确保始终指定您希望字节表示的编码。如果只使用string.getBytes(),它将使用平台默认值。(并非所有平台都使用相同的默认值)

import java.security.*;

..

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

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

如果你有很多数据,看看.update(xxx)方法,它可以被重复调用。然后调用.digest()来获得结果散列。

其他回答

是我做的…似乎还行-我相信有人会指出错误…

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

下面是我如何使用它:

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

来自Apache Commons项目的Hex。

试试这个:

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 "";
    }
}
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或sha1,类似于php函数(md5, 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