package org.fluxtream.core.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.jetbrains.annotations.NotNull; /** * <p> * <code>HashUtils</code> helps compute hashes. * </p> * * @author Chris Bartley (bartley@cmu.edu) */ public final class HashUtils { /** * Creates a SHA-256 hash for the given <code>bytes</code> and returns it as a {@link String} of hex bytes. * Guaranteed to not return <code>null</code>, but might throw a {@link NoSuchAlgorithmException} if the SHA-256 * algorithm is not available. * * @throws NoSuchAlgorithmException */ @NotNull public static String computeSha256Hash(@NotNull final byte[] bytes) throws NoSuchAlgorithmException { return computeHash(bytes, "SHA-256"); } /** * Creates an MD5 hash for the given <code>bytes</code> and returns it as a {@link String} of hex bytes. * Guaranteed to not return <code>null</code>, but might throw a {@link NoSuchAlgorithmException} if the MD5 * algorithm is not available. * * @throws NoSuchAlgorithmException */ @NotNull public static String computeMd5Hash(final byte[] bytes) throws NoSuchAlgorithmException { return computeHash(bytes, "MD5"); } /** Converts the given byte to a (zero-padded, if necessary) hex {@link String}. */ private static String byteToHexString(final byte b) { final String s = Integer.toHexString(b & 0xff); return (s.length() == 1) ? "0" + s : s; } @NotNull private static String computeHash(@NotNull final byte[] bytes, @NotNull final String algorithm) throws NoSuchAlgorithmException { final MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // add the bytes to the digest messageDigest.update(bytes); // compute the digest final byte[] digest = messageDigest.digest(); // convert the digest bytes into hex final StringBuilder hash = new StringBuilder(); for (final byte b : digest) { hash.append(byteToHexString(b)); } return hash.toString().toLowerCase(); } private HashUtils() { // private to prevent instantiation } }