Tuesday, December 22, 2009

Easy Hex SHA-1/MD5 Hashes with Groovy

The Java API has included support for a number of cryptographic hash functions ( MD5, SHA-1, etc) since Java 1.4 via the java.security.MessageDigest class. If you ever tried to use these in a web-centric context you've probably been a bit annoyed by the fact that it only provides hash results as byte arrays. Here's a quick and easy solution using Groovy that I thought I'd share:


def messageDigest = MessageDigest.getInstance("SHA1")
messageDigest.update( stringToHash.getBytes() );
def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft( 40, '0' )


Notice the padding of zeros since the length of the SHA-1 hex needs to be 40 characters. If you're using a different hashing hex string length will change.

Note: Code updated to reflect an improvement submitted in the comments.

Labels:

2 Comments:

At December 22, 2009 at 11:46 PM , Blogger Tim Yates said...

If you change it to:

def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft( 40, '0' )

I believe you can do away with the padding loop in your code :)

 
At January 27, 2011 at 4:50 AM , Blogger mbjarland said...

Here's a snippet for calculating SHA1 hashes for files. In contrast to a lot of posts out there this also handles large files, i.e. files too large to load into memory. Works for other data as well with minor modifications:

import java.security.MessageDigest

int KB = 1024
int MB = 1024*KB

File f = new File(args[0])
if (!f.exists() || !f.isFile()) {
println "Invalid file provided"
}

def messageDigest = MessageDigest.getInstance("SHA1")

long start = System.currentTimeMillis()

f.eachByte(MB) { byte[] buf, int bytesRead ->
messageDigest.update(buf, 0, bytesRead);
}

def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft( 40, '0' )
long delta = System.currentTimeMillis()-start

println "$sha1Hex took $delta ms to calculate"

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home