Obtenir le total de contrôle MD5 D'un fichier en Java

je cherche à utiliser Java pour obtenir la somme de contrôle MD5 d'un fichier. J'ai été vraiment surpris mais je n'ai pas pu trouver quoi que ce soit qui montre comment obtenir la somme de contrôle MD5 d'un fichier.

Comment fait-on?

425
demandé sur Hamedz 2008-11-20 06:45:39

21 réponses

il y a un décorateur de flux d'entrée, java.security.DigestInputStream , de sorte que vous pouvez calculer le digest tout en utilisant le flux d'entrée comme vous le feriez normalement, au lieu d'avoir à faire 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();
480
répondu erickson 2015-10-21 16:01:56

Utiliser DigestUtils à partir de Apache Commons Codec de la bibliothèque:

FileInputStream fis = new FileInputStream(new File("foo"));
String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(fis);
fis.close();
254
répondu Leif Gruenwoldt 2017-08-04 00:56:05

il y a un exemple à Java-How-to de Real en utilisant la classe MessageDigest .

Vérifiez cette page pour les exemples utilisant CRC32 et SHA-1 ainsi.

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();
       }
   }
}
145
répondu Bill the Lizard 2017-11-06 01:59:54

Le com.Google.commun.hash API offres:

  • une API conviviale unifiée pour toutes les fonctions de hachage
  • Seedable 32 et 128 bits implémentations de murmur3
  • md5(), sha1(), sha256(), SHA512() adaptateurs, changer une seule ligne de code pour passer entre ceux-ci, et murmure.
  • goodFastHash(int bits), pour quand vous ne vous souciez pas ce que l'algorithme que vous utilisez
  • Utilités générales pour les instances de HashCode, comme combineOrdered / combineUnordered

Lire le Guide de l'Utilisateur ( IO Expliqué , "1519210920 de" Hachage Expliqué ).

Pour votre cas d'utilisation Files.hash() calcule et renvoie le digest de la valeur pour un fichier.

, par exemple a calcul par digestion (changer SHA-1 en MD5 en MD5) get MD5 digest)

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

notez que est beaucoup plus rapide que , donc utilisez si vous n'avez pas besoin d'un checksum cryptographique sécurisé. Notez également que ne doit pas être utilisé pour stocker les mots de passe et similaires, car il est trop facile de forcer, pour les mots de passe utiliser , ou à la place.

Pour la protection à long terme avec des hachages un Merkle signature scheme ajoute à la sécurité et à La Poste de la Cryptographie Quantique Groupe d'Étude commandité par la Commission Européenne a recommandé l'utilisation de cette cryptographie pour la protection à long terme contre les ordinateurs quantiques ( ref ).

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

84
répondu oluies 2017-12-15 21:20:23

utilisant nio2 (Java 7+) et 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 un total de contrôle attendu:

String expected = "2252290BC44BEAD16AA1BF89948472E8";
String actual = DatatypeConverter.printHexBinary(hash);
System.out.println(expected.equalsIgnoreCase(actual) ? "MATCH" : "NO MATCH");
43
répondu assylias 2016-05-23 10:30:11

Guava fournit maintenant une nouvelle API de hachage cohérente qui est beaucoup plus conviviale que les divers API de hachage fournis dans le JDK. Voir "151940920 De" Hachage Expliqué . Pour un fichier, vous pouvez obtenir la somme MD5, CRC32 (avec la version 14.0+) ou beaucoup d'autres hachages facilement:

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();
33
répondu ColinD 2013-07-04 15:36:07

Ok. J'ai dû ajouter. Une implémentation en ligne pour ceux qui ont déjà la dépendance de Spring et D'Apache Commons ou qui prévoient de l'ajouter:

DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file))

et Apache commons option (crédit @duleshi):

DigestUtils.md5Hex(FileUtils.readFileToByteArray(file))

J'espère que ça aidera quelqu'un.

23
répondu MickJ 2015-08-07 15:43:53

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 avez besoin d'imprimer ce tableau d'octets. Utiliser comme ci-dessous

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

si vous avez besoin d'une chaîne hexagonale. Utiliser comme ci-dessous

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

où DatatypeConverter est javax.XML.lier.DatatypeConverter

21
répondu sunil 2014-10-31 08:23:19

j'ai récemment dû faire cela pour juste une chaîne dynamique, MessageDigest peut représenter le hachage de nombreuses façons. Pour obtenir la signature du fichier comme vous l'obtiendriez avec la commande md5sum je devais faire quelque chose comme 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 façon de le faire spécifiquement pour un fichier, la réponse ci-dessus traite de ce calme bien. Je viens de passer beaucoup de temps obtenir la somme pour ressembler à la plupart de l'application l'afficher, et pensé que vous pourriez rencontrer les mêmes problèmes.

13
répondu Brian Gianforcaro 2012-09-05 22:42:19
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 /

11
répondu Jam 2012-12-31 06:22:55

nous utilisions un code qui ressemble au code ci-dessus dans un post précédent en utilisant

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

cependant, attention à utiliser BigInteger.toString() ici, car il tronquera les zéros de tête... (pour un exemple, essayez s = "27" , la somme de contrôle doit être "02e74f10e0327ad868d138f2b4fdd6f0" )

j'appuie la suggestion D'Utiliser Apache Commons Codec, j'ai remplacé notre propre code avec cela.

8
répondu user552999 2017-01-05 19:42:02
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
répondu F.X 2010-07-12 15:43:28

méthode Java très rapide et propre qui ne repose pas sur des bibliothèques externes:

(il suffit de remplacer MD5 par SHA-1, SHA-256, SHA-384 ou SHA-512 si vous les voulez)

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);
}
7
répondu David Onter 2016-01-07 21:05:11

une Autre mise en œuvre: Fast MD5 mise en Œuvre en Java

String hash = MD5.asHex(MD5.getHash(new File(filename)));
6
répondu Lukasz R. 2011-03-16 13:10:27

Standard de Java Runtime Environnement :

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 à Linux md5sum utility.

6
répondu gotozero 2013-10-17 12:43:08
String checksum = DigestUtils.md5Hex(new FileInputStream(filePath));
6
répondu Ravikiran kalal 2016-08-27 22:01:55

Voici une fonction simple qui enroule autour du code de Sunil pour qu'il prenne un fichier comme paramètre. La fonction n'a pas besoin de bibliothèques externes, mais elle nécessite 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
5
répondu stackoverflowuser2010 2016-12-09 22:25:40

si vous utilisez ANT pour construire, c'est très simple. Ajoutez ce qui suit à votre Compilation.xml:

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

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

pour en savoir plus, cliquez ici.

3
répondu Matt Brock 2010-07-09 20:04:05

Google guava 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
3
répondu Balaji Boggaram Ramanarayan 2013-10-23 23:37:19
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
répondu XXX 2014-03-24 06:54:02

voici une variante pratique qui utilise InputStream.transferTo() de Java 9, et OutputStream.nullOutputStream() de Java 11. Il ne nécessite pas de bibliothèques externes et n'a pas besoin de charger tout le 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"
0
répondu Bill 2018-09-08 22:27:06