Question

Je cherche à utiliser Java pour obtenir la somme de contrôle MD5 d'un fichier. J'étais vraiment surpris mais je n'ai rien trouvé qui montre comment obtenir la somme de contrôle MD5 d'un fichier.

Comment cela se fait-il?

Était-ce utile?

La solution

Il existe un décorateur de flux d'entrée, java.security.DigestInputStream , afin que vous puissiez calculer le résumé en utilisant le flux d'entrée comme vous le feriez normalement, au lieu de devoir effectuer un passage supplémentaire sur les données. .

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

Autres conseils

Utilisez DigestUtils de la bibliothèque du codec Apache Commons :

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

Vous trouverez un exemple dans le le guide de procédures Java de Real à l'aide du classe MessageDigest .

Consultez cette page pour des exemples utilisant CRC32 et SHA-1 également.

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

Le com .google.common.hash API propose:

  • Une API conviviale unifiée pour toutes les fonctions de hachage
  • Implémentations de murmur3 32 et 128 bits pouvant être ensemencées
  • Adaptateurs md5 (), sha1 (), sha256 (), sha512 (), modifiez une seule ligne de code pour basculer entre eux et le murmure.
  • goodFastHash (int bits), pour le choix de l'algorithme que vous utilisez
  • Utilitaires généraux pour les instances HashCode, tels que combineOrdered / combineUnordered

Lisez le guide de l'utilisateur ( Explication des entrées / sorties , Explication du hachage ).

Pour votre cas d'utilisation Files.hash () calcule et retourne la valeur de résumé d'un fichier.

Par exemple, un

est beaucoup plus rapide que < une classe = "post-tag" href = "/ questions / tagged / md5" title = "affiche les questions étiquetées 'md5'" rel = "tag"> md5 , utilisez donc si vous n'avez pas besoin d'une somme de contrôle sécurisée de manière cryptographique. Notez également que les ne doivent pas être utilisées pour stocker des mots de passe. et ainsi de suite puisqu'il est trop facile de faire usage de la force, pour les mots de passe, utilisez , ou

Pour une protection à long terme avec les hachages, un schéma de signature de Merkle ajoute à la sécurité et à The Post Quantum Un groupe d'étude sur la cryptographie, parrainé par la Commission européenne, a recommandé l'utilisation de cette cryptographie pour la protection à long terme contre les ordinateurs quantiques ( ref ).

Notez que a un taux de collision plus élevé que les autres.

Utilisation de nio2 (Java 7+) et d’aucune bibliothèque externe:

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

Pour comparer le résultat avec une somme de contrôle attendue:

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

Guava fournit désormais une nouvelle API de hachage cohérente, beaucoup plus conviviale que les différents outils de hachage. API fournies dans le JDK. Voir Le hachage expliqué . Pour un fichier, vous pouvez obtenir facilement la somme MD5, CRC32 (avec la version 14.0+) ou de nombreux autres hachages:

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

Ok. Je devais ajouter. Implémentation sur une ligne pour ceux qui ont déjà une dépendance Spring et Apache Commons ou qui envisagent de l’ajouter:

DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file))

Option réservée uniquement à Apache (crédits @duleshi):

DigestUtils.md5Hex(FileUtils.readFileToByteArray(file))

J'espère que cela aide quelqu'un.

Une approche simple sans bibliothèques tierces utilisant Java 7

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

Si vous devez imprimer ce tableau d'octets. Utiliser comme ci-dessous

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

Si vous avez besoin d'une chaîne hexadécimale en dehors de ce résumé. Utiliser comme ci-dessous

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

où DatatypeConverter est javax.xml.bind.DatatypeConverter

J'ai récemment eu à le faire pour une chaîne dynamique. MessageDigest peut représenter le hachage de nombreuses façons. Pour obtenir la signature du fichier comme vous le feriez avec le md5sum commande je devais faire quelque chose comme le ceci:

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

Cela ne répond évidemment pas à votre question sur la manière de le faire spécifiquement pour un fichier, la réponse ci-dessus traite de ce problème en douceur. Je viens de passer beaucoup de temps à faire en sorte que la somme ressemble à celle de la plupart des applications, et je pensais que vous pourriez rencontrer le même problème.

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

Ou vous pouvez obtenir plus d'informations http://www.asjava.com/core-java/java-md5-example/

Nous utilisions un code semblable au code ci-dessus dans une publication précédente utilisant

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

Cependant, faites attention à l’utilisation de BigInteger.toString () ici, car cela tronquerait les zéros de tête ... (pour un exemple, essayez s = "27" , la somme de contrôle doit être "02e74f10e0327ad868d868d138f2b4fdd6f0 )

J'appuie la suggestion d'utiliser Apache Commons Codec, j'ai remplacé notre propre code par celui-là.

Très rapide & amp; méthode Java propre qui ne repose pas sur des bibliothèques externes:

(Remplacez simplement MD5 par SHA-1, SHA-256, SHA-384 ou SHA-512 si vous le souhaitez)

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

Autre implémentation: mise en œuvre rapide de MD5 en Java

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

Manière d'environnement d'exécution Java standard :

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

Le résultat est égal à celui de l'utilitaire linux md5sum.

Voici une fonction simple qui enveloppe le code de Sunil afin qu’il prenne un fichier comme paramètre. La fonction ne nécessite aucune bibliothèque externe, mais 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);            
    }


}

Exemple de sortie:

hex=B117DD0C3CBBD009AC4EF65B6D75C97B

Si vous utilisez ANT pour construire, c'est très simple. Ajoutez les éléments suivants à votre build.xml:

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

Où jarFile est le JAR contre lequel vous souhaitez générer le MD5 et toDir est le répertoire dans lequel vous souhaitez placer le fichier MD5.

Plus d'informations ici.

Google Gava fournit une nouvelle API. Trouvez celui ci-dessous:

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

Voici une variante pratique qui utilise InputStream.transferTo () de Java 9 et OutputStream.nullOutputStream () de Java 11. Il ne nécessite aucune bibliothèque externe. et n'a pas besoin de charger l'intégralité du fichier en mémoire.

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

et

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

retourne

"e30fa2784ba15be37833d569280e2163c6f106506dfb9b07dde67a24bfb90da65c661110cf2c5c6f71185754ee5ae3fd83a5465c92f72abd888b03187229da29"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top