【问题标题】:MySQL MD5 and Java MD5 not equalMySQL MD5 和 Java MD5 不相等
【发布时间】:2010-11-05 06:12:18
【问题描述】:

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

生成

94-190-34-148-236-208-224-240-142-171-118-144-210-166-238-105

【问题讨论】:

    标签: java mysql cryptography md5 cryptographic-hash-function


    【解决方案1】:

    尝试以 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();
    }
    

    【讨论】:

    • @Randolpho: 如果 b
    • 好点;编辑以包括@mihi 的检查(这比 IMO 更好的字节值检查)。
    • 你忘记了 hex.length() 中的 ()
    • 啊,复制/粘贴的危险。 :) 已修复。
    【解决方案2】:

    替换

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

    通过

    String hex = Integer.toHexString((int) 0x00FF & b);
    if (hex.length == 1) sb.append("0");
    sb.append( hex );
    

    【讨论】:

    • 如果可以的话,我会给你超过 +1。 :)
    【解决方案3】:

    使用 Apache Commons Codec 库 (http://commons.apache.org/codec) 中的实用程序类可以将其缩短为单行代码

    String md = org.apache.commons.codec.digest.DigestUtils.md5hex("whatever");
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          考虑将十进制字节转换为十六进制。例如 94 base 10 是 5e base 16。

          【讨论】:

            【解决方案7】:
            String password = org.springframework.util.DigestUtils.md5DigestAsHex("password".getBytes())
            System.out.println(password)
            

            【讨论】:

              【解决方案8】:

              与其重新发明轮子,不如尝试使用 Apache commons 编解码器 (http://commons.apache.org/codec/),它将使用 Hex.encodeHex(byte[]) 为您处理十六进制编码

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

              【讨论】:

                【解决方案9】:

                使用 Apache Commons Codec 库中的实用程序类:http://commons.apache.org/codec/

                String password = org.apache.commons.codec.digest.DigestUtils.md5Hex("password");
                System.out.println(password);
                

                【讨论】:

                  【解决方案10】:

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

                  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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多