Some time ago, I had the idea that a checksum calculation could be added to the FreshMarker File library. FreshMarker File is an extension for FreshMarker to support the Java types File and Path. A checksum support would allow the current checksum to be added to lists of files without any major detours. The idea is quite simple. A corresponding built-in is appended behind a file or path variable.
name: ${path?name}
MD5: ${path?md5}
SHA-256: ${path?sha256}
The template shown here displays the name of a file and its MD5 or SHA-256 checksums.
Checksums can be easily calculated in Java using the existing on-board tools.
private static TemplateString checksum(String algorithm, Path value) {
try (SeekableByteChannel ch = Files.newByteChannel(value, StandardOpenOption.READ)) {
MessageDigest md = MessageDigest.getInstance(algorithm);
ByteBuffer bf = ByteBuffer.allocate(1000);
while (ch.read(bf) > 0) {
bf.flip();
md.update(bf);
bf.clear();
}
byte[] digest = md.digest();
return new TemplateString(new BigInteger(1, digest).toString(16));
} catch (NoSuchAlgorithmException | IOException ex) {
throw new ProcessException("cannot calculate digest", ex);
}
}
The method shown here uses the MessageDigest class to calculate a checksum from the contents of a file. MessageDigest typically offers MD5, SHA1, SHA-256, SHA-384, and SHA-512 as algorithms, so we provide plugins for all five.
register.add(TemplatePath.class, "md5", (x, y, e) -> checksum((TemplatePath)x, e, "MD5")); register.add(TemplatePath.class, "sha", (x, y, e) -> checksum((TemplatePath)x, e, "SHA-1")); register.add(TemplatePath.class, "sha1", (x, y, e) -> checksum((TemplatePath)x, e, "SHA-1")); register.add(TemplatePath.class, "sha256", (x, y, e) -> checksum((TemplatePath)x, e, "SHA-256")); register.add(TemplatePath.class, "sha384", (x, y, e) -> checksum((TemplatePath)x, e, "SHA-384")); register.add(TemplatePath.class, "sha512", (x, y, e) -> checksum((TemplatePath)x, e, "SHA-512")); register.add(TemplateFile.class, "md5", (x, y, e) -> checksum((TemplateFile)x, e, "MD5")); register.add(TemplateFile.class, "sha", (x, y, e) -> checksum((TemplateFile)x, e, "SHA-1")); register.add(TemplateFile.class, "sha1", (x, y, e) -> checksum((TemplateFile)x, e, "SHA-1")); register.add(TemplateFile.class, "sha256", (x, y, e) -> checksum((TemplateFile)x, e, "SHA-256")); register.add(TemplateFile.class, "sha384", (x, y, e) -> checksum((TemplateFile)x, e, "SHA-384")); register.add(TemplateFile.class, "sha512", (x, y, e) -> checksum((TemplateFile)x, e, "SHA-512"));
This completes the implementation. For an image file named pandemoinum.png with the content shown on the left, the output on the right is generated.

name: pandemonium.png MD5: e41549a50dc7f2abb5463176c77ee71a SHA-256: f091aaa9a206aff762181bde2f1197e20b1e9039815eb9f0b53aced1c28ff165
The built-ins are included in the latest version of FreshMarker File 2.5.3. Enjoy!