Java – Create file checksum with SHA and MD5
In this article, we will show you how to use a SHA-256 and MD5 algorithm to generate a checksum for a file.
- MessageDigest.getInstance(“algorithm”)
- Apache Commons Codec
1. MessageDigest
d:\server.log
hello world
1.1 Generate a file checksum with a SHA256 algorithm.
FileCheckSumSHA.java
package com.mkyong.hashing;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class FileCheckSumSHA {
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
MessageDigest md = MessageDigest.getInstance("SHA-256"); //SHA, MD2, MD5, SHA-256, SHA-384...
String hex = checksum("d:\\server.log", md);
System.out.println(hex);
}
private static String checksum(String filepath, MessageDigest md) throws IOException {
// file hashing with DigestInputStream
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md)) {
while (dis.read() != -1) ; //empty loop to clear the data
md = dis.getMessageDigest();
}
// bytes to hex
StringBuilder result = new StringBuilder();
for (byte b : md.digest()) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}
Output
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
1.2 Generate a file checksum with a MD5 algorithm.
FileCheckSumMD5.java
package com.mkyong.hashing;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class FileCheckSumMD5 {
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
MessageDigest md = MessageDigest.getInstance("MD5");
String hex = checksum("d:\\server.log", md);
System.out.println(hex);
}
private static String checksum(String filepath, MessageDigest md) throws IOException {
// DigestInputStream is better, but you also can hash file like this.
try (InputStream fis = new FileInputStream(filepath)) {
byte[] buffer = new byte[1024];
int nread;
while ((nread = fis.read(buffer)) != -1) {
md.update(buffer, 0, nread);
}
}
// bytes to hex
StringBuilder result = new StringBuilder();
for (byte b : md.digest()) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}
Output
5eb63bbbe01eeed093cb22bb8f5acdc3
2. Apache Commons Codec
pom.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
2.1 File checksum.
FileCheckSum.java
package com.mkyong.hashing;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.FileInputStream;
import java.io.IOException;
public class App {
public static void main(String[] args) throws IOException {
String checksumSHA256 = DigestUtils.sha256Hex(new FileInputStream("d:\\server.log"));
System.out.println("checksumSHA256 : " + checksumSHA256);
String checksumMD5 = DigestUtils.md5Hex(new FileInputStream("d:\\server.log"));
System.out.println("checksumMD5 : " + checksumMD5);
}
}
Output
checksumSHA256 : b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
checksumMD5 : 5eb63bbbe01eeed093cb22bb8f5acdc3
Hi I am using this code, but checksum or hash are different in different systems like windows and Linux hashes will not match. can you please tell me, how to achieve.
i have been asked to produce a software which demands a person to enter either a text,file etc and produces in return hex from a sha 224 and 512 hash.i would love to do it in java but not only don’t i know how to call a file in a java program and i don’t how to go about writing the sha 224 and 512 programs.please help me
I’will have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s,one with cheese and a large soda
Nice post,
Worked well for txt files.
Can I find SHA-1 checksum for a encrypted pgp file or a zip file?
Thanks,
Shashant
Great work. Thank you!
I got java.lang.ArrayIndexOutOfBoundsException when I use this method in my code. I wonder why? It stopped when the current seq.No=977 in int
Basically the seqNoinbytes[i] in md.update has value -47. I wonder how I can use this with a 4-bytes seq.No with value 977, and probably the other numbers.
Why are you adding 0x100?
If you simple use Integer.toString((byte & 0xFF), 16) you would get the same result.
Adding 0x100 to the number and converting it to String will preserve leading zeroes. That’s why substring(1) is needed to truncate the “hundreds”.
The result looks prettier, nothing else.
Example:
b + 0 = b –toString–> “b”
b + 100 = 10b –toString–> “10b” –substring–> “0b”
hi anon, thanks for the tips ~
Interesting approach, how does it compare to using the CheckedInputStream?
i never use CheckedInputStream before, would you mind to share your experience ?
It works well: javadoc
Example (identical to readying any stream):
try
{
// Compute Adler-32 checksum
CheckedInputStream cis = new CheckedInputStream(new FileInputStream("filename"), new Adler32());
byte[] tempBuf = new byte[128];
while (cis.read(tempBuf) >= 0){}
long checksum = cis.getChecksum().getValue();
} catch (IOException e) {
}
You might consider using Adler32 instead of SHA1. It’s a whole lot faster. That is of-course unless you are using the checksum as some sort of identifier for the file, in which case the size of SHA1’s hash might be helpful.
http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/Adler32.html
http://www.anomalousanomaly.com/docs/CheckMark%20Results.pdf
Thanks for the suggestion and links provided. I always SHA-1 to generate the checksum value for the file, will look into the Adler32~
Nice post,
exclent approch, I used the code and It worked fine
Thanks for bringing this up