0

I want to create a program, which generates a MD5-hash from the input of a path. The code down below only creates a hash from the name of the path. How can I generate a MD5-hash from the input of the path? Thank you!

public static void main (String[]args) {
    Scanner sc = new Scanner(System.in);
    
    
    String path = sc.next();
    System.out.println("MD5: "+MD5(path)); //Methode MD5 auf "path" angewandt
}

public static String MD5(String input) {
    
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] messageDigest = md.digest(input.getBytes());
        BigInteger number = new BigInteger (1, messageDigest);
        String hashtext = number.toString(16);
        while (hashtext.length()<32) {
            hashtext = "0" + hashtext;
        }
        return hashtext;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    
}
Massin_NYC
  • 29
  • 1
  • 6
  • The hash may start with more than one zero which is then suppressed by BigInteger.toString(16). Therefore I strongly recommend to use a different way to convert the digest to hex. – Robert Apr 12 '21 at 15:57

1 Answers1

1

You could read the content of the file by using:

String filepath = "" ; // the full path from system.in
byte[] content = Files.readAllBytes(Paths.get(filepath));

After that, you could get the hash of this bytes array:

public static byte[] MD5(byte[] data) {
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(data);
        return messageDigest.digest();
    }
    catch(Exception e){
        // any processing
    }
}

for displying the binary content (the bytes array) or send it as string, you could convert it safely using any base-16/32/64 encoding:

String hashString = Base64.getEncoder().encodeToString(bytesArray);

So final code could be:

import java.nio.file.*;
import java.util.*;
import java.security.*;

public class Demo {
    public static void main (String[]args) throws Exception {
        Scanner sc = new Scanner(System.in);
        String path = sc.nextLine(); // read all the string from keyboard
        
        byte[] content = Files.readAllBytes(Paths.get(path));
        byte[] hash = MD5(content);
        
        String hashString = Base64.getEncoder().encodeToString(hash);
        System.out.println("MD5: "+ hashString); 
    }
    
    public static byte[] MD5(byte[] data) throws Exception{
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(data);
        return messageDigest.digest();
    }    
}
Wajdy Essam
  • 4,280
  • 3
  • 28
  • 33
  • Thank you but I still don't get the same MD5 hash as an output for 2 paths with the same contents. Where could the mistake be that the output depends on the Pathname and not the contents of the path? – Massin_NYC Apr 15 '21 at 16:22
  • The above code compute hash based on file content not the path, so if the hash is different then the files not having the same content, for sure! Try to hash the same file twice and you will see same output, after that copy the file and compute the new copied file and you will get the same output. – Wajdy Essam Apr 15 '21 at 20:50
  • Thank you it worked now. But is there a possible way to create a MD5 hash for a path with more files in it instead of only one file. – Massin_NYC Apr 19 '21 at 13:09
  • You means hashing all the files inside this path? you could enumrate the files first (see https://stackoverflow.com/questions/4917326/how-to-iterate-over-the-files-of-a-certain-directory-in-java/4917347) then do for-loop for each file and apply the above code. – Wajdy Essam Apr 19 '21 at 13:41