Hi,
does anyone know an efficient way to create checksum in JavaScript?
Hi Nino,
at first I thought that should be either feasible with some JS script out there or - if not available - definitely with some Java library offered by medini. Then I read about JSum in this article and recognized that JSum is partially right: for normal hashes it matters whether you have a data before the other one, for JSON it might not be right because semantically { a:'foo':, b:'bar' } is the same as { b:'bar', a:'foo': }.
Anyway, I did not try to get JSUm running in medini scripting. All I can offer is a straight way to directly use internal Java classes to generate an MD5 (or other) hash, look at this:
var text1 = '.....';var text2 = '.....';var md = java.security.MessageDigest.getInstance('MD5');md.update(text1.getBytes("UTF8"));md.update(text2.getBytes("UTF8"));...var lastHash = md.digest();var prettyHash = javax.xml.bind.DatatypeConverter.printHexBinary(lastHash).toLowerCase();
I hope that this gives you, and anyone else having the same or similar question a start.
Happy Scripting
Jan
Thank you Jan,
unfortunately I do not understand the solution
By reading the article I understand that the author caters to a very specific issue which is order of elements in a Java object. I don't have that issue, my objects are well formed.
I now use this snipped that I found in an otherwise empty drawer, it works a treat
function checksum(s){ var chk = 0x12345678; var len = s.length; for (var i = 0; i < len; i++) { chk += (s.charCodeAt(i) * (i + 1)); } return (chk & 0xffffffff).toString(16);}
Nice, I assume s is an array, I was rather referring to a Java Script object.
Anyway, glad you found this solution.
s is actually a string here, I now edited the above post and changed the variable "s" to "text" to make it more obvious
Hi Jan,
Do you have a full snippet for generating MD5 (or SHA256 for that matter) of a string using the java libraries? (Nino's solution above apparently is unique for small strings only).
Somewhat I am not able to adapt your code above using java libraries... for example it does not seem to understand the getBytes method, so maybe I have to import/load something before (?)
Thanks for any help!
Cheers, Andre
Andre,
my bad. The getBytes() method is part of the java.lang.String API, not the JS string.
The MessageDigest accepts only BLOBs, so byte[]. We either have to find a way to convert a JS string to bytes (there are some articles arround) or you have to convert a JS string to a Java String first:
var javaString = new java.lang.String('foo bar');
var bytes = javaString.getBytes(...)
Maybe you can take it from here.
Regards
Thanks a lot! Now it works. I put the snippet below for completeness.
// create md5 instance var md = java.security.MessageDigest.getInstance('MD5'); // string to be hashed var myJSString = 'Liberté, Egalité, Fraternité'; var javaString = new java.lang.String(myJSString); //actual hashing md.update(javaString.getBytes("UTF8")); var lastHash = md.digest(); var prettyHash = javax.xml.bind.DatatypeConverter.printHexBinary(lastHash).toLowerCase(); //result should be: 9f232781d916abd12f528fba71dbacb7 console.log(prettyHash);
Nice, I like 'Liberté, Egalité, Fraternité' :-)
If you agree, I could add this to the helper.js so everyone has it for the future-
Sure!
I only tested successfully the code above in the v2020R2 version. When I tried it this morning
in the v2023R1.1, I get the error below. Any ideas of why is that happening?
Regards, Andre
Not 100% sure but javax.xml may has changed when we moved to Java 11. We may have to find another way to pretty print the hash value.
Andre, it might be that the javax.xml package is simply not anymore in the standard classpath and you have to use "bind" to load it from the "javax.xml.bind" bundle.
I did not find the time to prove this though.
this worked for me as expected:
var DatatypeConverter = bind("javax.xml.bind", "javax.xml.bind.DatatypeConverter", false);....var prettyHash = DatatypeConverter.printHexBinary(lastHash).toLowerCase();
Thanks for the feedback on the bind approach. I've found another solution as well so I put them as alternatives in the snippet below. Both are working on v2020 and v2023.
// create md5 instance var md = java.security.MessageDigest.getInstance('MD5'); // string to be hashed var myJSString = 'Liberté, Egalité, Fraternité'; var javaString = new java.lang.String(myJSString); //actual hashing md.update(javaString.getBytes("UTF8")); var lastHash = md.digest(); // option 1 (comment option 2) var prettyHash = new java.lang.String.format("%032x", new java.math.BigInteger(1, lastHash)); // option 2 (comment option 1) // var DatatypeConverter = bind("javax.xml.bind", "javax.xml.bind.DatatypeConverter", false);// var prettyHash = DatatypeConverter.printHexBinary(lastHash).toLowerCase(); // output should be 9f232781d916abd12f528fba71dbacb7 console.log(prettyHash);
Very cool Andre,
that solution is even smarter because it doe snot introduce another dependency, well done.
I found an (the?) article on stackoverflow and that solution was not (yet?) the one with the highest votes as it is rather new.
Cool stuff