MD5 Генерирует 31 символьный хэш в Java

Я использую следующий код для генерации хешей MD5:

public static String encode(String data) throws Exception {

    /* Check the validity of data */
    if (data == null || data.isEmpty()) {
        throw new IllegalArgumentException("Null value provided for "
                + "MD5 Encoding");
    }

    /* Get the instances for a given digest scheme MD5 or SHA */
    MessageDigest m = MessageDigest.getInstance("MD5");

    /* Generate the digest. Pass in the text as bytes, length to the
     * bytes(offset) to be hashed; for full string pass 0 to text.length()
     */
    m.update(data.getBytes(), 0, data.length());

    /* Get the String representation of hash bytes, create a big integer
     * out of bytes then convert it into hex value (16 as input to
     * toString method)
     */
    String digest = new BigInteger(1, m.digest()).toString(16);

    return digest;
}

Когда я запускаю вышеуказанный сегмент кода со строковыми данными как [12, B006GQIIEM, MH-ANT2000], вывод представляет собой хэш-символ 31 символа - 268d43a823933c9dafaa4ac0e756d6a.

Есть ли проблема с хеш-функцией MD5 или есть некоторая проблема в коде выше?

Ответ 1

Единственная проблема в вашем коде, когда MSB меньше, чем Ox10, в хэш-строке результата будет только 31 байт, вместо 32 байтов отсутствует нулевой.

Создайте строку md5 таким образом:

            byte messageDigest[] = m.digest();

            hexString = new StringBuffer();
            for (int i=0;i<messageDigest.length;i++) {
                String hex=Integer.toHexString(0xFF & messageDigest[i]);
                if(hex.length()==1)
                    hexString.append('0');

                hexString.append(hex);
            }

Ответ 2

Вы можете попробовать следующее:

...
String digest = String.format("%032x", new BigInteger(1, m.digest()));

Примечание: это "%032x", а не "%32x".

Ответ 3

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

import java.io.UnsupportedEncodingException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

public class MySimpleMD5 { 

private static String convertToHex(byte[] data) { 
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) { 
        int halfbyte = (data[i] >>> 4) & 0x0F;
        int two_halfs = 0;
        do { 
            if ((0 <= halfbyte) && (halfbyte <= 9)) 
                buf.append((char) ('0' + halfbyte));
            else 
                buf.append((char) ('a' + (halfbyte - 10)));
            halfbyte = data[i] & 0x0F;
        } while(two_halfs++ < 1);
    } 
    return buf.toString();
} 

public static String MD5(String text) 
throws NoSuchAlgorithmException, UnsupportedEncodingException  { 
    MessageDigest md;
    md = MessageDigest.getInstance("MD5");
    byte[] md5hash = new byte[32];
    md.update(text.getBytes("iso-8859-1"), 0, text.length());
    md5hash = md.digest();
    return convertToHex(md5hash);
 } 
} 

Ответ 4

Вы также можете попробовать следующее:

private static String getMd5Hash(String input) throws NoSuchAlgorithmException {
    MessageDigest m = MessageDigest.getInstance("MD5");

    byte[] data = m.digest(EncodingUtils.getBytes(input, "UTF8"));

    StringBuilder sBuilder = new StringBuilder();

    for (int i = 0; i < data.length; i++) {

        for (byte b : data) {
            if(b == 0x00){
                sBuilder.append("00");
            } else if ((b & 0x0F) == b) {
                sBuilder.append("0");
                break;
            } else {
                break;
            }
        }

        BigInteger bigInt = new BigInteger(1, data);
        sBuilder.append(bigInt.toString(16));
    }

    // Return the hexadecimal string.
    return sBuilder.toString().substring(0, 32);
}