IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Caculer le checksum MD5 d'un fichier


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 11
    Points
    11
    Par défaut Caculer le checksum MD5 d'un fichier
    Bonjour tout le monde!

    Ma question est dans le titre, j'aimerais calculé le checksum MD5 d'un fichier avec le langage JAVA (afin de développer une applet qui vérifie le checksum).

    Je l'ai déjà fais en php grace aux fonctions file_get_contents() et md5().

    Y a t il des fonctions similaires en JAVA ? J'ai déja essayé pas mal de truc notamment avec MessageDigest.getInstance("MD5") mais le checksum obtenu n'est pas identique a celui en php (qui celui ci est bon car je l'ai vérifié avec un logiciel de calcul de checksum MD5)

    Merci pour votre aide!!

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Cela fonctionne très bien avec MessageDigest.getInstance("MD5")...
    C'est juste que le tableau de byte retourné correspond aux valeurs binaires et non pas à une représentation ascii utilisé généralement pour afficher le résultat...

    Il suffit donc de transformer ce tableau en une String plus lisible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	private static String digest(final byte[] buf) {
    		final String HEX_DIGITS = "0123456789abcdef";
    		final StringBuilder sb = new StringBuilder(buf.length * 2);
    		for (int i = 0; i < buf.length; i++) {
    			int b = buf[i] & 0xFF;
    			sb.append(HEX_DIGITS.charAt(b >>> 4))
    				.append(HEX_DIGITS.charAt(b & 0xF));
    		}
    		return sb.toString();
    	}
    a++

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Merci pour ta réponse!
    J'affiche deja le résultat sous forme héxadécimale...

    En fait je pense que le soucis vient des sauts de ligne.

    Avec :
    "Hello world! bonjour!"

    J'ai bien le meme checksum qu'en php (avec les fonctions file_get_contents() et md5 ())

    Or avec :
    "Hello world!

    bonjour!"

    Les 2 checksums sont différents...

    Quelqu'un aurai t il une idée ?

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par overjey Voir le message
    Quelqu'un aurai t il une idée ?
    Tu lis depuis un fichier ou tu utilises seulement une variable dans le code ?

    Si tu es dans le second cas cela signifie que tu n'utilises pas les même fin de ligne (\r\n ou \n selon le cas), ce qui fausse ton résultat...

    a++

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    En fait j'utilise une variable qui contient le contenu de mon fichier et je fais un md5 sur cette variable...

    Faut-il que je remplace tous les \n\r et \n de ma variable par "" ?

  6. #6
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Non...


    Il faudrait surtout voir ton code...

    a++

  7. #7
    Membre à l'essai
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    public class Checksum extends java.applet.Applet {
     
            public void init (){
     
    	Frame parent = new Frame();
    	FileDialog fd = new FileDialog(parent, "Please choose a file",FileDialog.LOAD);
    	fd.show();
    	String selectedItem = fd.getFile();
    	if (selectedItem == null) {
    		// no file selected
    	} else {
    		File ffile = new File( fd.getDirectory() + File.separator +
    		        fd.getFile());
    		try {
    			RandomAccessFile fic = new RandomAccessFile(ffile, "r");
    			StringBuffer chaine = new StringBuffer();
    			String temp = "";
    			String contents = loadFile(ffile);
    			while ((temp = fic.readLine())!= null)	
    				chaine.append(temp);
     
    			fic.close();
     
    			System.out.println(Checksum.md5(contents));
     
    		} catch (IOException fnf) {
    			System.out.println("Fichier non trouvé");
    			fnf.printStackTrace();
    		}
    	}
       }
     
      public static String loadFile(File f) {
    	     try {
    	        BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
    	        StringWriter out = new StringWriter();
    	        int b;
    	        while ((b=in.read()) != -1)
    	            out.write(b);
    	        out.flush();
    	        out.close();
    	        in.close();
    	        return out.toString();
    	     }
    	     catch (IOException ie)
    	     {
    	          ie.printStackTrace(); 
    	          return null;
    	     }
     
    	 }
     
     
    	public static String hex(byte[] array) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < array.length; ++i) {
                sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).toUpperCase().substring(1,3));
            }
            return sb.toString();
        }
        public static String md5 (String message) { 
            try { 
                MessageDigest md = MessageDigest.getInstance("MD5"); 
                return hex (md.digest(message.getBytes("CP1252"))); 
            } catch (NoSuchAlgorithmException e) { 
            } catch (UnsupportedEncodingException e) { 
            } 
            return null;
        }
     
    }

  8. #8
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Ton problème vient clairement de la lecture du fichier...

    Déjà tu ne précises pas l'encodage lors de la lecture, ce qui peut amener a quelques surprise si el fichier n'est pas exactemetn dans l'encodage par défaut.
    Ensuite tu utilises readLine() qui supprime les fins de ligne... ce qui provoquera obligatoirement un résultat différent !

    Il serait préférable de rester aux niveaux des bytes pour ne pas dénaturer le contenu binaire du fichier...

    D'autres remarques sur ton code :
    • Ne jamais ignorer une exception !!!
    • Toujours utiliser un try/finally pour libérer proprement les flux



    Bref, pour ton md5() je verais plutôt quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	public static String md5 (byte[] data) { 
            try { 
                MessageDigest md = MessageDigest.getInstance("MD5"); 
                return hex (md.digest(data)); 
            } catch (Exception e) {
            	// Ne jamais ignorer une exception,
            	// même si elle n'arrivera jamais
            	throw new RuntimeException(e);
            }
        }
    En utilisant un FileInputStream pour lire le fichier dans un byte[]



    Ou alors, en lisant le fichier bout à bout (ce qui doit permettre d'économiser la mémoire avec de très gros fichier) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    	public static String md5 (InputStream source) { 
            try { 
                MessageDigest md = MessageDigest.getInstance("MD5");
                byte[] buf = new byte[8096];
                int len;
     
                while ( (len=source.read(buf)) >= 0 ) {
                	md.update(buf, 0, len);
                }
                return hex (md.digest()); 
            } catch (Exception e) {
            	// Ne jamais ignorer une exception,
            	// même si elle n'arrivera jamais
            	throw new RuntimeException(e);
            }
        }
    Cela permet de lire le fichier bout à bout et de ne pas le charger en entier en mémoire (surtout s'il est très gros) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		InputStream in = new FileInputStream("lefichier");
    		try {
    			String value = md5(in);
    		} finally {
    			in.close();
    		}

    a++

  9. #9
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par overjey Voir le message
    Merci pour ta réponse!
    J'affiche deja le résultat sous forme héxadécimale...

    En fait je pense que le soucis vient des sauts de ligne.

    Avec :
    "Hello world! bonjour!"

    J'ai bien le meme checksum qu'en php (avec les fonctions file_get_contents() et md5 ())

    Or avec :
    "Hello world!

    bonjour!"

    Les 2 checksums sont différents...

    Quelqu'un aurai t il une idée ?
    J'ai peut-être mal compris ce que tu voulais dire, mais c'est normal qu'ils n'aient pas le même checksum puisque dans le second cas tu as 2 retours à la ligne en plus ! C'est le but du checksum, 2 chaines différentes ont un checksum différent (avec une proba de collision de 2⁻¹²⁸ pour le md5)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo -e 'Hello world! bonjour!' | md5sum
    e0fae21cce40907b63813359b62ccba2  -
    $ echo -e 'Hello world!\n\nbonjour!' | md5sum
    5c8bbb3d5af667922d09bee85fdc5f1e  -

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ®om Voir le message
    J'ai peut-être mal compris ce que tu voulais dire, mais c'est normal qu'ils n'aient pas le même checksum puisque dans le second cas tu as 2 retours à la ligne en plus ! C'est le but du checksum, 2 chaines différentes ont un checksum différent (avec une proba de collision de 2⁻¹²⁸ pour le md5)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo -e 'Hello world! bonjour!' | md5sum
    e0fae21cce40907b63813359b62ccba2  -
    $ echo -e 'Hello world!\n\nbonjour!' | md5sum
    5c8bbb3d5af667922d09bee85fdc5f1e  -
    Je crois qu'il voulait dire "différent entre java et php"

Discussions similaires

  1. [WD15] Hash MD5 d'un fichier sur FTP
    Par VincentRoy dans le forum WinDev
    Réponses: 9
    Dernier message: 04/05/2011, 14h43
  2. Checksum md5 en javasript
    Par fatalgamers dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/08/2010, 14h33
  3. Checksum MD5 d'un fichier
    Par overjey dans le forum Langage
    Réponses: 2
    Dernier message: 24/06/2008, 09h26
  4. Choix et calcul CRC, checksum,md5
    Par mercure07 dans le forum C++
    Réponses: 1
    Dernier message: 22/04/2008, 14h27
  5. Calculer le MD5 d'un fichier octet par octet
    Par bouazza92 dans le forum C
    Réponses: 5
    Dernier message: 09/08/2006, 20h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo