Skip to content

Instantly share code, notes, and snippets.

@scoroberts
Created October 16, 2019 01:03
Show Gist options
  • Save scoroberts/a60d61a2cc3afba1e8813b338ecd1501 to your computer and use it in GitHub Desktop.
Save scoroberts/a60d61a2cc3afba1e8813b338ecd1501 to your computer and use it in GitHub Desktop.
Test of different Java based SHA-256 hash implementations
@Grab(group='com.google.guava', module='guava', version='19.0')
@Grab(group='commons-codec', module='commons-codec', version='1.13')
@Grab(group='bouncycastle', module='bcprov-jdk15', version='140')
import groovy.transform.CompileStatic
import java.security.MessageDigest
import java.nio.charset.StandardCharsets
import com.google.common.hash.Hashing
import org.apache.commons.codec.digest.DigestUtils
import org.bouncycastle.crypto.digests.SHA256Digest
//test string for all hashing implementations
String test = "lwkjt23uy45pojsdf;lnwo45y23po5i;lknwe;lknasdflnqw3uo5"
String hashJava(String str){
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(str.getBytes(StandardCharsets.UTF_8));
return bytesToHex(encodedhash)
}
@CompileStatic
String bytesToHex(byte[] hash) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
@CompileStatic
String groovyHash(String str){
str.digest('SHA-256')
}
@CompileStatic
String guavaHash(String str){
Hashing.sha256().hashString(str, StandardCharsets.UTF_8).toString();
}
@CompileStatic
String apacheHash(String str){
DigestUtils.sha256Hex(str)
}
@CompileStatic
String bouncyHash(String str){
SHA256Digest digest = new SHA256Digest();
byte[] keyByteArray = str.getBytes(StandardCharsets.UTF_8)
byte[] output = new byte[digest.getDigestSize()];
digest.update(keyByteArray, 0, keyByteArray.length);
digest.doFinal(output, 0);
bytesToHex(output)
}
long iterations = 100_0000
println "Hashing ${iterations} iterations of SHA-256"
//warm up, throw away
for (int x=0; x<1000; x++) hashJava(test)
long start = System.currentTimeMillis()
for (int x=0; x<iterations; x++) hashJava(test)
long end = System.currentTimeMillis()
println ("time java: ${end-start}\t\t${iterations*1000/(end-start)} hashes/sec")
for (int x=0; x<1000; x++) groovyHash(test)
start = System.currentTimeMillis()
for (int x=0; x<iterations; x++) groovyHash(test)
end = System.currentTimeMillis()
println ("time groovy: ${end-start}\t${iterations*1000/(end-start)} hashes/sec")
for (int x=0; x<1000; x++) apacheHash(test)
start = System.currentTimeMillis()
for (int x=0; x<iterations; x++) apacheHash(test)
end = System.currentTimeMillis()
println ("time apache: ${end-start}\t\t${iterations*1000/(end-start)} hashes/sec")
for (int x=0; x<1000; x++) guavaHash(test)
start = System.currentTimeMillis()
for (int x=0; x<iterations; x++) guavaHash(test)
end = System.currentTimeMillis()
println ("time guava: ${end-start}\t\t${iterations*1000/(end-start)} hashes/sec")
for (int x=0; x<1000; x++) bouncyHash(test)
start = System.currentTimeMillis()
for (int x=0; x<iterations; x++) bouncyHash(test)
end = System.currentTimeMillis()
println ("time bouncy: ${end-start}\t\t${iterations*1000/(end-start)} hashes/sec")
@scoroberts
Copy link
Author

I thought the same thing and moved them around. I ended up getting the same results -- and consistently the same results. I have also heard that Guava wraps standard, but there too I get better results. If you can find where they get similar results, that would be helpful.

@XZTDean
Copy link

XZTDean commented Jan 31, 2022

I think bytesToHex function makes the performance for MessageDigest and commons-codec different. If make both hashJava and apacheHash return byte[] to avoid transforming to hex string. Then they can get similar results.

@scoroberts
Copy link
Author

scoroberts commented Feb 1, 2022 via email

@scoroberts
Copy link
Author

Took advice to remove the String conversion portions here: https://gist.github.com/scoroberts/77cc2d5c28fa2faeb1626d8eb39ec8c8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment