الحصول على المجموع الاختباري MD5 للملف في Java

StackOverflow https://stackoverflow.com/questions/304268

  •  08-07-2019
  •  | 
  •  

سؤال

إنني أتطلع إلى استخدام Java للحصول على المجموع الاختباري MD5 للملف.لقد فوجئت حقًا ولكني لم أتمكن من العثور على أي شيء يوضح كيفية الحصول على المجموع الاختباري MD5 للملف.

كيف يتم ذلك؟

هل كانت مفيدة؟

المحلول

وهناك تيار المدخلات الديكور، java.security.DigestInputStream، بحيث يمكنك حساب هضم أثناء استخدام دفق الإدخال كما تفعل عادة، بدلا من الاضطرار إلى من تمرير كرة عرضية اضافية على البيانات.

MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"));
     DigestInputStream dis = new DigestInputStream(is, md)) 
{
  /* Read decorated stream (dis) to EOF as normal... */
}
byte[] digest = md.digest();

نصائح أخرى

استخدم DigestUtils مكتبة اباتشي العموم ترميز :

try (InputStream is = Files.newInputStream(Paths.get("file.txt"))) {
    String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(is);
}

وهناك مثال على ريال مدريد جافا كيف ل باستخدام <ل أ href = "http://docs.oracle.com/javase/6/docs/api/java/security/MessageDigest.html" يختلط = "noreferrer"> MessageDigest الطبقة .

وتأكد من أن الصفحة للحصول على أمثلة باستخدام CRC32 وSHA-1 أيضا.

import java.io.*;
import java.security.MessageDigest;

public class MD5Checksum {

   public static byte[] createChecksum(String filename) throws Exception {
       InputStream fis =  new FileInputStream(filename);

       byte[] buffer = new byte[1024];
       MessageDigest complete = MessageDigest.getInstance("MD5");
       int numRead;

       do {
           numRead = fis.read(buffer);
           if (numRead > 0) {
               complete.update(buffer, 0, numRead);
           }
       } while (numRead != -1);

       fis.close();
       return complete.digest();
   }

   // see this How-to for a faster way to convert
   // a byte array to a HEX string
   public static String getMD5Checksum(String filename) throws Exception {
       byte[] b = createChecksum(filename);
       String result = "";

       for (int i=0; i < b.length; i++) {
           result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
       }
       return result;
   }

   public static void main(String args[]) {
       try {
           System.out.println(getMD5Checksum("apache-tomcat-5.5.17.exe"));
           // output :
           //  0bb2827c5eacf570b6064e24e0e6653b
           // ref :
           //  http://www.apache.org/dist/
           //          tomcat/tomcat-5/v5.5.17/bin
           //              /apache-tomcat-5.5.17.exe.MD5
           //  0bb2827c5eacf570b6064e24e0e6653b *apache-tomcat-5.5.17.exe
       }
       catch (Exception e) {
           e.printStackTrace();
       }
   }
}

ال com.google.common.hash عروض واجهة برمجة التطبيقات:

  • واجهة برمجة تطبيقات موحدة سهلة الاستخدام لجميع وظائف التجزئة
  • تطبيقات murmur3 القابلة للبذور 32 و128 بت
  • تقوم محولات md5() وsha1() وsha256() وsha512() بتغيير سطر واحد فقط من التعليمات البرمجية للتبديل بينها، وتذمر.
  • GoodFastHash(int bits)، لأنه عندما لا تهتم بالخوارزمية التي تستخدمها
  • أدوات مساعدة عامة لمثيلات HashCode، مثل CombineOrdered / CombineUnordered

اقرأ دليل المستخدم (وأوضح إيو, وأوضح التجزئة).

لحالة الاستخدام الخاصة بك Files.hash() يحسب ويعيد قيمة الملخص للملف.

على سبيل المثال أ حساب الملخص (قم بتغيير SHA-1 إلى MD5 للحصول على ملخص MD5)

HashCode hc = Files.asByteSource(file).hash(Hashing.sha1());
"SHA-1: " + hc.toString();

لاحظ أن أسرع بكثير من , ، لذا استخدم إذا كنت لا تحتاج إلى مجموع اختباري آمن للتشفير.لاحظ ذلك أيضًا لا ينبغي استخدامها لتخزين كلمات المرور وما شابه ذلك لأنه من السهل استخدام القوة الغاشمة لاستخدام كلمات المرور , أو بدلاً من.

للحماية طويلة المدى باستخدام التجزئة أ مخطط توقيع ميركل يضيف إلى الأمان وقد أوصت مجموعة دراسة ما بعد التشفير الكمي التي ترعاها المفوضية الأوروبية باستخدام هذا التشفير للحماية طويلة المدى ضد أجهزة الكمبيوتر الكمومية (المرجع).

لاحظ أن لديها معدل تصادم أعلى من غيرها.

وعن طريق nio2 (جافا 7+) وتوجد مكتبات الخارجية:

byte[] b = Files.readAllBytes(Paths.get("/path/to/file"));
byte[] hash = MessageDigest.getInstance("MD5").digest(b);

لمقارنة النتيجة مع الاختباري المتوقع:

String expected = "2252290BC44BEAD16AA1BF89948472E8";
String actual = DatatypeConverter.printHexBinary(hash);
System.out.println(expected.equalsIgnoreCase(actual) ? "MATCH" : "NO MATCH");
يوفر

الجوافة الآن جديد، بما يتفق API التجزئة التي هي صديقة للمستخدم أكثر بكثير من التجزئة المختلفة واجهات برمجة التطبيقات المقدمة في JDK. انظر الثرم وأوضح . لملف، يمكنك الحصول على مبلغ MD5، CRC32 (مع نسخة 14.0+) أو عدة تجزئات أخرى بسهولة:

HashCode md5 = Files.hash(file, Hashing.md5());
byte[] md5Bytes = md5.asBytes();
String md5Hex = md5.toString();

HashCode crc32 = Files.hash(file, Hashing.crc32());
int crc32Int = crc32.asInt();

// the Checksum API returns a long, but it's padded with 0s for 32-bit CRC
// this is the value you would get if using that API directly
long checksumResult = crc32.padToLong();

وطيب. كان لي أن أضيف. تنفيذ سطر واحد بالنسبة لأولئك الذين لديهم بالفعل الربيع وأباتشي العموم التبعية أو تخطط لإضافته:

DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file))

لوالمشاعات أباتشي سوى خيار (duleshi الائتمان):

DigestUtils.md5Hex(FileUtils.readFileToByteArray(file))

وآمل أن يساعد هذا شخص.

ونهج بسيط مع أي طرف ثالث المكتبات باستخدام جافا 7

String path = "your complete file path";
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(Files.readAllBytes(Paths.get(path)));
byte[] digest = md.digest();

إذا كنت تحتاج لطباعة هذه المجموعة بايت. استخدام على النحو التالي

System.out.println(Arrays.toString(digest));

إذا كنت بحاجة إلى سلسلة عرافة من هذه الخلاصة. استخدام على النحو التالي

String digestInHex = DatatypeConverter.printHexBinary(digest).toUpperCase();
System.out.println(digestInHex);

وحيث DatatypeConverter هو javax.xml.bind.DatatypeConverter

لقد اضطررت مؤخرًا إلى القيام بذلك من أجل سلسلة ديناميكية فقط، MessageDigest يمكن أن تمثل التجزئة بعدة طرق.للحصول على توقيع الملف كما ستحصل عليه مع ملف MD5sum الأمر كان علي أن أفعل شيئًا مثل هذا:

try {
   String s = "TEST STRING";
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   md5.update(s.getBytes(),0,s.length());
   String signature = new BigInteger(1,md5.digest()).toString(16);
   System.out.println("Signature: "+signature);

} catch (final NoSuchAlgorithmException e) {
   e.printStackTrace();
}

من الواضح أن هذا لا يجيب على سؤالك حول كيفية القيام بذلك خصيصًا لملف ما، فالإجابة أعلاه تتعامل مع هذا الهدوء بشكل جيد.لقد أمضيت الكثير من الوقت في جعل المبلغ يبدو كما تعرضه معظم التطبيقات، واعتقدت أنك قد تواجه نفس المشكلة.

public static void main(String[] args) throws Exception {
    MessageDigest md = MessageDigest.getInstance("MD5");
    FileInputStream fis = new FileInputStream("c:\\apache\\cxf.jar");

    byte[] dataBytes = new byte[1024];

    int nread = 0;
    while ((nread = fis.read(dataBytes)) != -1) {
        md.update(dataBytes, 0, nread);
    };
    byte[] mdbytes = md.digest();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < mdbytes.length; i++) {
        sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
    }
    System.out.println("Digest(in hex format):: " + sb.toString());
}

وأو قد تحصل على المزيد من المعلومات http://www.asjava.com/core-java/java-md5-example/

وكنا باستخدام رمز يشبه رمز أعلاه في الوظيفة السابقة باستخدام

...
String signature = new BigInteger(1,md5.digest()).toString(16);
...

ولكن، انتبه لاستخدام BigInteger.toString() هنا، كما أنه سيتم اقتطاع الأصفار البادئة ... (للحصول على مثال، في محاولة s = "27"، ينبغي "02e74f10e0327ad868d138f2b4fdd6f0" الاختباري)

وأنا الثانية على اقتراح لاستخدام أباتشي العموم الترميز، أنا محل كود الخاصة بنا مع ذلك.

وسريع جدا ونظيفة جافا الطريقة التي لا تعتمد على المكتبات الخارجية:

و(ببساطة استبدال MD5 مع SHA-1، SHA-256، SHA-384 أو SHA-512 إذا كنت تريد تلك)

public String calcMD5() throws Exception{
        byte[] buffer = new byte[8192];
        MessageDigest md = MessageDigest.getInstance("MD5");

        DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("Path to file")), md);
        try {
            while (dis.read(buffer) != -1);
        }finally{
            dis.close();
        }

        byte[] bytes = md.digest();

        // bytesToHex-method
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }

        return new String(hexChars);
}
public static String MD5Hash(String toHash) throws RuntimeException {
   try{
       return String.format("%032x", // produces lower case 32 char wide hexa left-padded with 0
      new BigInteger(1, // handles large POSITIVE numbers 
           MessageDigest.getInstance("MD5").digest(toHash.getBytes())));
   }
   catch (NoSuchAlgorithmException e) {
      // do whatever seems relevant
   }
}
String checksum = DigestUtils.md5Hex(new FileInputStream(filePath));

وتنفيذ أخرى: تنفيذ MD5 السريع في جاوة

String hash = MD5.asHex(MD5.getHash(new File(filename)));

ستاندرد بيئة جافا طريقة :

public String checksum(File file) {
  try {
    InputStream fin = new FileInputStream(file);
    java.security.MessageDigest md5er =
        MessageDigest.getInstance("MD5");
    byte[] buffer = new byte[1024];
    int read;
    do {
      read = fin.read(buffer);
      if (read > 0)
        md5er.update(buffer, 0, read);
    } while (read != -1);
    fin.close();
    byte[] digest = md5er.digest();
    if (digest == null)
      return null;
    String strDigest = "0x";
    for (int i = 0; i < digest.length; i++) {
      strDigest += Integer.toString((digest[i] & 0xff) 
                + 0x100, 16).substring(1).toUpperCase();
    }
    return strDigest;
  } catch (Exception e) {
    return null;
  }
}

وكانت النتيجة تساوي المنفعة لينكس MD5SUM.

وهنا هو وظيفة بسيطة التي يلتف حولها كود سونيل بحيث أنه يأخذ ملف كمعلمة. وظيفة لا تحتاج إلى أي المكتبات الخارجية، ولكنها لا تتطلب جافا 7.

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.xml.bind.DatatypeConverter;

public class Checksum {

    /**
     * Generates an MD5 checksum as a String.
     * @param file The file that is being checksummed.
     * @return Hex string of the checksum value.
     * @throws NoSuchAlgorithmException
     * @throws IOException
     */
    public static String generate(File file) throws NoSuchAlgorithmException,IOException {

        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(Files.readAllBytes(file.toPath()));
        byte[] hash = messageDigest.digest();

        return DatatypeConverter.printHexBinary(hash).toUpperCase();
    }

    public static void main(String argv[]) throws NoSuchAlgorithmException, IOException {
        File file = new File("/Users/foo.bar/Documents/file.jar");          
        String hex = Checksum.generate(file);
        System.out.printf("hex=%s\n", hex);            
    }


}

والناتج مثال:

hex=B117DD0C3CBBD009AC4EF65B6D75C97B

إذا كنت تستخدم ANT لبناء، وهذا هو ميتة بسيطة. إضافة ما يلي إلى build.xml الخاص بك:

<checksum file="${jarFile}" todir="${toDir}"/>

وأين jarFile هو JAR تريد توليد MD5 ضد، وtoDir هو الدليل الذي تريد وضع ملف MD5.

مزيد من المعلومات هنا.

وجوجل الجوافة يوفر API الجديد. العثور على واحد أدناه:

public static HashCode hash(File file,
            HashFunction hashFunction)
                     throws IOException

Computes the hash code of the file using hashFunction.

Parameters:
    file - the file to read
    hashFunction - the hash function to use to hash the data
Returns:
    the HashCode of all of the bytes in the file
Throws:
    IOException - if an I/O error occurs
Since:
    12.0
public static String getMd5OfFile(String filePath)
{
    String returnVal = "";
    try 
    {
        InputStream   input   = new FileInputStream(filePath); 
        byte[]        buffer  = new byte[1024];
        MessageDigest md5Hash = MessageDigest.getInstance("MD5");
        int           numRead = 0;
        while (numRead != -1)
        {
            numRead = input.read(buffer);
            if (numRead > 0)
            {
                md5Hash.update(buffer, 0, numRead);
            }
        }
        input.close();

        byte [] md5Bytes = md5Hash.digest();
        for (int i=0; i < md5Bytes.length; i++)
        {
            returnVal += Integer.toString( ( md5Bytes[i] & 0xff ) + 0x100, 16).substring( 1 );
        }
    } 
    catch(Throwable t) {t.printStackTrace();}
    return returnVal.toUpperCase();
}

وهنا هو الاختلاف مفيد أن يجعل استخدام InputStream.transferTo() من جاوة 9، وOutputStream.nullOutputStream() من جاوة 11. انها لا تحتاج الى المكتبات الخارجية ولا تحتاج إلى تحميل الملف بأكمله في الذاكرة.

public static String hashFile(String algorithm, File f) throws IOException, NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance(algorithm);

    try(BufferedInputStream in = new BufferedInputStream((new FileInputStream(f)));
        DigestOutputStream out = new DigestOutputStream(OutputStream.nullOutputStream(), md)) {
        in.transferTo(out);
    }

    String fx = "%0" + (md.getDigestLength()*2) + "x";
    return String.format(fx, new BigInteger(1, md.digest()));
}

و

hashFile("SHA-512", Path.of("src", "test", "resources", "some.txt").toFile());

وعوائد

"e30fa2784ba15be37833d569280e2163c6f106506dfb9b07dde67a24bfb90da65c661110cf2c5c6f71185754ee5ae3fd83a5465c92f72abd888b03187229da29"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top