MySQL MD5和Java MD5不相等

MySQL MD5和Java MD5不相等,java,mysql,cryptography,md5,cryptographic-hash-function,Java,Mysql,Cryptography,Md5,Cryptographic Hash Function,MySQL中的下一个函数 MD5('secret')生成5ebe2294ecd0e0f08eab7690d2a6ee69 我希望有一个Java函数来生成相同的输出。但是 public static String md5( String source ) { try { MessageDigest md = MessageDigest.getInstance( "MD5" ); byte[] bytes = md.digest( source.getByte

MySQL中的下一个函数

MD5('secret')
生成5ebe2294ecd0e0f08eab7690d2a6ee69

我希望有一个Java函数来生成相同的输出。但是

public static String md5( String source ) {
    try {
        MessageDigest md = MessageDigest.getInstance( "MD5" );
        byte[] bytes = md.digest( source.getBytes("UTF-8") );
        return getString( bytes );
    } catch( Exception e )  {
        e.printStackTrace();
        return null;
    }
}

private static String getString( byte[] bytes ) {
    StringBuffer sb = new StringBuffer();
    for( int i=0; i<bytes.length; i++ ) {
        byte b = bytes[ i ];
        sb.append( ( int )( 0x00FF & b ) );
        if( i+1 <bytes.length ) {
            sb.append( "-" );
        }
    }
    return sb.toString();
}

尝试用16进制编码。只是为了让你开始。。。基16中的94为5E

**编辑:**尝试更改getString方法:

private static String getString( byte[] bytes ) 
{
  StringBuffer sb = new StringBuffer();
  for( int i=0; i<bytes.length; i++ )     
  {
     byte b = bytes[ i ];
     String hex = Integer.toHexString((int) 0x00FF & b);
     if (hex.length() == 1) 
     {
        sb.append("0");
     }
     sb.append( hex );
  }
  return sb.toString();
}
私有静态字符串getString(字节[]字节)
{
StringBuffer sb=新的StringBuffer();

对于(int i=0;i请考虑将十进制字节转换为十六进制。例如,94 base 10是5e base 16。

这两个字节相等。Java字节似乎是十进制的。请将其转换为十六进制。

这是因为基数不同。MySQL MD5结果是base-16,而Java MD5是base-10

我希望我能进一步帮助你,但我的数学糟透了。我的一个朋友帮我用PHP中的base-16校验和生成base-10校验和,但我丢失了脚本。希望你能在此基础上找到答案。

替换

sb.append( ( int )( 0x00FF & b ) );
if( i+1 <bytes.length ) {
    sb.append( "-" );
}

与其重新发明轮子,不如尝试ApacheCommonsCodec(),它将使用hex.encodeHex(字节[])为您处理十六进制编码


通过使用apachecommons编解码器库()中的实用程序类,可以将其缩短为一行代码


使用Apache Commons编解码器库中的实用程序类:


看看我是怎么做的,代码是可以自我解释的

Java代码:

public static void main(String a[]) throws NoSuchAlgorithmException {
    String passClear = "cleartext";
    MessageDigest md5 = MessageDigest.getInstance("MD5"); // you can change it to SHA1 if needed!
    md5.update(passClear.getBytes(), 0, passClear.length());
    System.out.printf("MD5: %s: %s ", passClear, new BigInteger(1, md5.digest()).toString(16));
}
输出:

MD5:明文:5ab677ec767735cebd67407005786016

产生相同哈希的Mysql查询:

SELECT md5( 'cleartext' ); 
输出:

md5(“明文”)

5ab677ec767735cebd67407005786016

@Randolpho:如果b<0x10,你需要用0来填充优秀的点;编辑以包含@mihi的检查(这比字节值检查更好)。你忘了十六进制中的()了。length()啊,复制/粘贴的危险已经修复。如果可以,我会给你+1以上。)
private String encodeAsMD5(String password) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = md.digest(password.getBytes());
        return new String(Hex.encodeHex(bytes));
    } 
    catch(Exception e) {
        e.printStackTrace();
        return null;
    }
}
String md = org.apache.commons.codec.digest.DigestUtils.md5hex("whatever");
String password = org.apache.commons.codec.digest.DigestUtils.md5Hex("password");
System.out.println(password);
String password = org.springframework.util.DigestUtils.md5DigestAsHex("password".getBytes())
System.out.println(password)
public static void main(String a[]) throws NoSuchAlgorithmException {
    String passClear = "cleartext";
    MessageDigest md5 = MessageDigest.getInstance("MD5"); // you can change it to SHA1 if needed!
    md5.update(passClear.getBytes(), 0, passClear.length());
    System.out.printf("MD5: %s: %s ", passClear, new BigInteger(1, md5.digest()).toString(16));
}
SELECT md5( 'cleartext' );