Thursday 31 May 2012

Hexadecimal MD5 on Groovy

I always though java.security.MessageDigest would return a 32 long hash from its digest() method, but I didn't realized that's only half of the way. Well I looked for some accurate implementation of the problem and I found a good one (I'm afraid is in Spanish). The following is is my humble translation to Groovy. (Of course hex array should be static final somewhere)

import java.security.MessageDigest

def groovyMD5Hash(somethingToHash){
        def hex = [ '0', '1', '2', '3','4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ]
        def md = MessageDigest.getInstance("MD5")
        def bytes = md.digest(somethingToHash.getBytes("UTF-8"))        
        def result = bytes.inject(""){acc,b->
            def high = (b & 0xf0) >> 4
            def low = b & 0x0f            
            acc + "${hex[high]}${hex[low]}"            
        }  
    }

UPDATE: (Thanks to betopica)

The thing is I didn't know about the method encodeHex() included by Groovy in the Byte[] class (you can check it out at http://groovy.codehaus.org/groovy-jdk/java/lang/Byte[].html ). Now the code is considerably shorter:


import java.security.MessageDigest

def shorterGroovyMD5Hash(somethingToHash){
   MessageDigest.getInstance("MD5").
       digest(somethingToHash.getBytes("UTF-8")).
       encodeHex().
   toString()
}

The method encodeHex() returns a groovy.lang.Writable object, but the implementation of that object defines a toString() method which translates the Writable object into a String. After a while looking for the implementation I've found it here inside the groovy-core project at Github.

2 comments:

  1. Great! But, do you know the bytes[] class has a encodeHex() in Groovy? :)

    http://groovy.codehaus.org/groovy-jdk/java/lang/Byte[].html

    ReplyDelete
  2. I had no idea. I'm gonna update the entry to add the modified method. It's even more accurate and efficient. Thanks for the tip :-)

    ReplyDelete