【问题标题】:Get MD5 String from Message Digest从消息摘要中获取 MD5 字符串
【发布时间】:2011-07-25 02:55:25
【问题描述】:

我了解它是如何工作的,但是如果我想将 MD5 打印为字符串,我该怎么做?

public static void getMD5(String fileName) throws Exception{
    InputStream input =  new FileInputStream(fileName);
    byte[] buffer = new byte[1024];

    MessageDigest hash = MessageDigest.getInstance("MD5");
    int read;
    do {
        read = input.read(buffer);
        if (read > 0) {
            hash.update(buffer, 0, read);
        }
    } while (read != -1);
    input.close();
}

【问题讨论】:

    标签: java md5 message digest


    【解决方案1】:

    致电hash.digest() 以完成该过程。它将返回一个字节数组。

    您可以使用 String 构造函数从 byte[] 创建一个字符串,但是如果您想要一个十六进制字符串,则必须手动循环遍历字节数组并计算出字符。

    【讨论】:

      【解决方案2】:

      首先你需要得到MessageDigest的byte[]输出:

      byte[] bytes = hash.digest();
      

      你不能轻易地打印它(例如new String(bytes)),因为它将包含没有良好输出表示的二进制文件。但是,您可以将其转换为十六进制以进行显示:

      StringBuilder sb = new StringBuilder(2 * bytes.length);
      for (byte b : bytes) {
          sb.append("0123456789ABCDEF".charAt((b & 0xF0) >> 4));
          sb.append("0123456789ABCDEF".charAt((b & 0x0F)));
      }
      String hex = sb.toString();
      

      【讨论】:

      • 感谢您提及实际问题,以及在字节字符串中的第一个想法,即仅使用字符串构造函数。此外,我很惊讶没有人建议使用 Base64。 Base64 与这些 HexToBinary 答案相比如何。
      【解决方案3】:

      试试这个

      StringBuffer hexString = new StringBuffer();
      MessageDigest md = MessageDigest.getInstance("MD5");
      byte[] hash = md.digest();
      
      for (int i = 0; i < hash.length; i++) {
          if ((0xff & hash[i]) < 0x10) {
              hexString.append("0"
                      + Integer.toHexString((0xFF & hash[i])));
          } else {
              hexString.append(Integer.toHexString(0xFF & hash[i]));
          }
      }
      

      【讨论】:

      【解决方案4】:
          String input = "168";
          MessageDigest md = MessageDigest.getInstance("MD5");
          byte[] md5sum = md.digest(input.getBytes());
          String output = String.format("%032X", new BigInteger(1, md5sum));
      

      或

      DatatypeConverter.printHexBinary( MessageDigest.getInstance("MD5").digest("a".getBytes("UTF-8")))
      

      【讨论】:

      • DatatypeConverter 不在 JDK9 中
      • 是的,我只是在查看用于 lib 的临时 hack,但是对于这个问题,不依赖于已弃用代码的答案会更好。
      • BigInteger 在前导十六进制数字为 0 时似乎存在问题。
      【解决方案5】:

      您还可以使用 Apache Commons Codec 库。 该库在DigestUtils 类中包含方法public static String md5Hex(InputStream data) 和public static String md5Hex(byte[] data)。 无需自己发明;)

      【讨论】:

        【解决方案6】:

        你可以少写一点:

        String hex = (new HexBinaryAdapter()).marshal(md5.digest(YOUR_STRING.getBytes()))
        

        【讨论】:

        • 不知道这里有没有性能方面的考虑?假设我们重用了一个 HexBinaryAdapter,与我们自己进行位操作相比,这会带来任何显着的开销吗?我们需要大量使用此代码,因为我们使用 URL 的 MD5 作为图像缓存的键。
        • Java 的源代码是公开的。 :) HexBinaryAdapter.marshal() 只调用DatatypeConverter.printHexBinary() (如果你想避免实例化HexBinaryAdapter,你实际上可以使用它),这反过来又在第一次被调用时实例化一个单例DatatypeConverterImpl。之后,只需直接致电DatatypeConverterImpl 的printHexBinary。它使用的方法与 WhiteFang34 的答案非常相似。
        • HexBinaryAdapter 不在 JDK9 中
        【解决方案7】:

        这是@anything 答案的另一个版本:

        StringBuilder sb = new StringBuilder();
        
        for (int i = 0; i < digest.length; i++) {
            if ((0xff & digest[i]) < 0x10) {
                sb.append("0").append(Integer.toHexString((0xFF & digest[i])));
            } else {
                sb.append(Integer.toHexString(0xFF & digest[i]));
            }
        }
        
        String result = sb.toString();
        

        【讨论】:

          【解决方案8】:
          /**
           * hashes:
           * e7cfa2be5969e235138356a54bad7fc4
           * 3c9ec110aa171b57bb41fc761130822c
           *
           * compiled with java 8 - 12 Dec 2015
           */
          public static String generateHash() {
              long r = new java.util.Random().nextLong();
              String input = String.valueOf(r);
              String md5 = null;
          
              try {
                  java.security.MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
                  //Update input string in message digest
                  digest.update(input.getBytes(), 0, input.length());
                  //Converts message digest value in base 16 (hex)
                  md5 = new java.math.BigInteger(1, digest.digest()).toString(16);
              }
              catch (java.security.NoSuchAlgorithmException e) {
                  e.printStackTrace();
              }
              return md5;
          }
          

          【讨论】:

            【解决方案9】:

            仅供参考...

            在某些情况下,这对我不起作用

            md5 = new java.math.BigInteger(1, digest.digest()).toString(16);
            

            但确实如此

            StringBuilder sb = new StringBuilder();
            
            for (int i = 0; i < digest.length; i++) {
                if ((0xff & digest[i]) < 0x10) {
                    sb.append("0").append(Integer.toHexString((0xFF & digest[i])));
                } else {
                    sb.append(Integer.toHexString(0xFF & digest[i]));
                }
            }
            
            String result = sb.toString();
            

            【讨论】:

            • 欢迎来到 Stack Overflow,@WillBerger !虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
            【解决方案10】:

            使用字节数组,消息摘要的结果:

            ...
            byte hashgerado[] = md.digest(entrada);
            ...
            
            for(byte b : hashgerado)
                System.out.printf("%02x", Byte.toUnsignedInt(b));
            

            结果(例如):
            89e8a9f68ad3c4bba9b9d3581cf5201d

            【讨论】:

              【解决方案11】:

              最短路径:

              String toMD5(String input) {
                  MessageDigest md = MessageDigest.getInstance("MD5");
                  byte[] raw = md.digest(input.getBytes());
                  return DatatypeConverter.printHexBinary(raw);
              }
              

              记得处理异常。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-01-05
                • 1970-01-01
                • 1970-01-01
                • 2023-03-10
                • 2019-05-11
                • 2016-09-17
                • 1970-01-01
                相关资源
                最近更新 更多