import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

private String asMD5Checksum(final String original) {
  final byte[] bytes = original.getBytes("UTF8");
  try {
    return new BigInteger(1, MessageDigest.getInstance("MD5").digest(bytes))
        .toString(16);
  } catch (NoSuchAlgorithmException e) {
    throw new RuntimeException(e);
  }
}

These digests aren't perfect, since they aren't going to be zero-padded, but it should do for simple use cases.

Consider leveraging ThreadLocal<MessageDigest>::get() to avoid instatiating MessageDigest on every call:

private static final ThreadLocal<MessageDigest> messageDigest = new ThreadLocal<MessageDigest>() {
  @Override
  protected MessageDigest initialValue() {
    try {
      return MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException(e);
    }
  }
};