it-swarm.com.de

Abrufen der MD5-Prüfsumme einer Datei in Java

Ich möchte Java verwenden, um die MD5-Prüfsumme einer Datei abzurufen. Ich war wirklich überrascht, aber ich konnte nichts finden, was zeigt, wie man die MD5-Prüfsumme einer Datei erhält.

Wie wird es gemacht?

474
Jack

Es gibt einen Eingabestream-Dekorator, Java.security.DigestInputStream, mit dem Sie den Digest berechnen können, während Sie den Eingabestream wie gewohnt verwenden, anstatt einen zusätzlichen Durchlauf über die Daten durchführen zu müssen.

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();
515
erickson

Verwenden Sie DigestUtils aus Apache Commons Codec der Bibliothek:

try (InputStream is = Files.newInputStream(Paths.get("file.Zip"))) {
    String md5 = org.Apache.commons.codec.digest.DigestUtils.md5Hex(is);
}
288
Leif Gruenwoldt

Es gibt ein Beispiel bei Real's Java-How-to mit der MessageDigest Klasse.

Auf dieser Seite finden Sie auch Beispiele mit CRC32 und 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();
       }
   }
}
156
Bill the Lizard

Die com.google.common.hash -API bietet Folgendes:

  • Eine einheitliche benutzerfreundliche API für alle Hash-Funktionen
  • Seedable 32- und 128-Bit-Implementierungen von murmur3
  • md5 (), sha1 (), sha256 (), sha512 () ändern nur eine Codezeile, um zwischen diesen zu wechseln, und murmeln.
  • goodFastHash (int bits), wenn es Ihnen egal ist, welchen Algorithmus Sie verwenden
  • Allgemeine Hilfsprogramme für HashCode-Instanzen, z. B. combineOrdered/combineUnordered

Lesen Sie die Bedienungsanleitung ( IO Explained , Hashing Explained ).

Für Ihren Anwendungsfall Files.hash() berechnet und gibt den Digest-Wert für eine Datei zurück.

Zum Beispiel eine sha-1 Digest-Berechnung (ändern Sie SHA-1 in MD5, um MD5-Digest zu erhalten)

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

Beachten Sie, dass crc32 viel schneller ist als md5 . Verwenden Sie crc32 , wenn Sie keine kryptografisch sichere Prüfsumme benötigen. Beachten Sie auch, dass md5 nicht zum Speichern von Passwörtern und dergleichen verwendet werden sollte, da dies zu einfach ist. Verwenden Sie für Passwörter bcrypt , scrypt oder sha-256 stattdessen.

Für langfristigen Schutz mit Hashes erhöht ein Merkle-Signaturschema die Sicherheit, und die von der Europäischen Kommission gesponserte Post-Quantum-Cryptography-Studiengruppe hat empfohlen, diese Kryptographie für den langfristigen Schutz vor Quantencomputern zu verwenden ( ref ).

Beachten Sie, dass crc32 eine höhere Kollisionsrate aufweist als die anderen.

86
oluies

Verwenden von nio2 (Java 7+) und keiner externen Bibliothek:

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

So vergleichen Sie das Ergebnis mit einer erwarteten Prüfsumme:

String expected = "2252290BC44BEAD16AA1BF89948472E8";
String actual = DatatypeConverter.printHexBinary(hash);
System.out.println(expected.equalsIgnoreCase(actual) ? "MATCH" : "NO MATCH");
54
assylias

Guava bietet jetzt eine neue, konsistente Hashing-API, die viel benutzerfreundlicher ist als die verschiedenen im JDK bereitgestellten Hashing-APIs. Siehe Hashing Explained . Für eine Datei können Sie die MD5-Summe, CRC32 (ab Version 14.0) oder viele andere Hashes einfach abrufen:

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();
37
ColinD

Okay. Ich musste hinzufügen. Einzeilige Implementierung für Benutzer, die bereits Spring- und Apache Commons-Abhängigkeiten haben oder diese hinzufügen möchten:

DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file))

Nur für und Apache Commons Option (credit @duleshi):

DigestUtils.md5Hex(FileUtils.readFileToByteArray(file))

Hoffe das hilft jemandem.

28
MickJ

Ein einfacher Ansatz ohne Bibliotheken von Drittanbietern mit Java 7

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

Wenn Sie dieses Byte-Array drucken müssen. Verwenden Sie als unten

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

Wenn Sie einen Hex-String aus diesem Digest benötigen. Verwenden Sie als unten

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

dabei ist DatatypeConverter javax.xml.bind.DatatypeConverter

23
sunil

Ich musste dies kürzlich nur für eine dynamische Zeichenfolge tun. MessageDigest kann den Hash auf verschiedene Arten darstellen. Um die Signatur der Datei zu erhalten, die Sie mit dem Befehl md5sum erhalten, musste ich Folgendes tun:

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

Dies beantwortet offensichtlich nicht Ihre Frage, wie es speziell für eine Datei zu tun ist. Die obige Antwort behandelt dies recht gut. Ich habe nur viel Zeit darauf verwendet, dass die Summe so aussieht, wie sie von den meisten Anwendungen angezeigt wird, und dachte, Sie könnten auf die gleichen Probleme stoßen.

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

Oder Sie erhalten weitere Informationen http://www.asjava.com/core-Java/java-md5-example/

11
Jam

Wir haben Code verwendet, der dem obigen Code in einem vorherigen Beitrag ähnelt

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

Achten Sie jedoch darauf, dass Sie hier BigInteger.toString() verwenden, da führende Nullen abgeschnitten werden ... (Beispiel: _s = "27"_, Prüfsumme sollte _"02e74f10e0327ad868d138f2b4fdd6f0"_ sein

Ich stimme dem Vorschlag zu, Apache Commons Codec zu verwenden. Ich habe unseren eigenen Code dadurch ersetzt.

9
user552999

Sehr schnelle und saubere Java-Methode, die keine externen Bibliotheken benötigt:

(Ersetzen Sie MD5 einfach durch SHA-1, SHA-256, SHA-384 oder SHA-512, wenn Sie diese benötigen.)

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);
}
8
David Onter
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
   }
}
7
F.X
String checksum = DigestUtils.md5Hex(new FileInputStream(filePath));
7
Ravikiran kalal

Hier ist eine einfache Funktion, die den Code von Sunil umschließt, sodass eine Datei als Parameter verwendet wird. Die Funktion benötigt keine externen Bibliotheken, benötigt jedoch Java 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);            
    }


}

Beispielausgabe:

hex=B117DD0C3CBBD009AC4EF65B6D75C97B

Standard Java Runtime Environment way :

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

Das Ergebnis entspricht dem Dienstprogramm linux md5sum.

6
gotozero

Eine weitere Implementierung: Schnelle MD5-Implementierung in Java

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

Wenn Sie ANT zum Erstellen verwenden, ist dies kinderleicht. Fügen Sie Ihrer build.xml Folgendes hinzu:

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

Wobei jarFile die JAR ist, für die Sie das MD5 generieren möchten, und toDir das Verzeichnis ist, in das Sie die MD5-Datei einfügen möchten.

Mehr Infos hier.

3
Matt Brock

Google Guave bietet eine neue API. Finden Sie die unten:

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

Hier ist eine praktische Variante, die InputStream.transferTo() von Java 9 und OutputStream.nullOutputStream() von Java 11 verwendet. Sie benötigt keine externen Bibliotheken und muss nicht Laden Sie die gesamte Datei in den Speicher.

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

und

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

kehrt zurück

"e30fa2784ba15be37833d569280e2163c6f106506dfb9b07dde67a24bfb90da65c661110cf2c5c6f71185754ee5ae3fd83a5465c92f72abd888b03187229da29"
2
Bill
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();
}
2
XXX