/* Copyright 2014 MITRE Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mitre.provenance.contenthash; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.MessageDigest; /** * In certain contexts, it may be useful to pair a PLUSObject with a hash of the contents of the data asset that it represents. * This abstract class provides methods and an interface useful for various content hashing algorithms. * @author moxious */ public abstract class ContentHasher { protected byte[] hashWith(InputStream is, MessageDigest digester) throws IOException { int length = 1024 * 8; byte[] bytes = new byte[length]; // Read in the bytes int offset = 0; int numRead = 0; while (numRead >= 0 && ((bytes.length-offset) > 0) && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { digester.update(bytes, offset, numRead); offset += numRead; } byte [] result = digester.digest(); digester.reset(); return result; } public abstract MessageDigest getDigest(); /** * Take the byte array that results from a content hasher, and format it as a text string. * Typically, byte arrays will contain non-printable binary data, this will clean it up to a hex * value suitable for use in Strings. * @param hashValue the byte array that came from a content hashing algorithm * @return a String value of the same, hex packed. */ public static String formatAsHexString(byte [] hashValue) { BigInteger bi = new BigInteger(1, hashValue); return String.format("%0" + (hashValue.length << 1) + "X", bi).toLowerCase(); } public byte[] hash(InputStream is) throws IOException { return hashWith(is, getDigest()); } // End hash } // End ContentHasher