/* * Copyright 2012, CMM, University of Queensland. * * This file is part of Paul. * * Paul is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Paul is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Paul. If not, see <http://www.gnu.org/licenses/>. */ package au.edu.uq.cmm.paul.grabber; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import au.edu.uq.cmm.paul.PaulException; /** * A collection of helpewr methods for ccreating and combining hashes. * * @author scrawley */ public class HashUtils { private static String ALGORITHM = "SHA-512"; private static int HASH_STRING_LENGTH = 128; // should the hash length in bytes * 2 public static String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { sb.append("0123456789ABCDEF".charAt(0xF & (b >> 4))); sb.append("0123456789ABCDEF".charAt(0xF & b)); } return sb.toString(); } public static byte[] hexStringToBytes(String str) throws InvalidHashException { byte[] res = new byte[str.length() / 2]; for (int i = 0; i < res.length; i++) { try { res[i] = Byte.parseByte(str.substring(i * 2, 2)); } catch (NumberFormatException ex) { throw new InvalidHashException("Hash string contains invalid characters"); } } return res; } public static String combineHashes(String hash1, String hash2) throws InvalidHashException { if (hash1 == null) { return hash2; } else if (hash2 == null) { return hash1; } if (hash1.length() != HASH_STRING_LENGTH || hash2.length() != HASH_STRING_LENGTH) { throw new InvalidHashException("Incorrect hash string length"); } byte[] h1 = hexStringToBytes(hash1); byte[] h2 = hexStringToBytes(hash2); for (int i = 0; i < h1.length; i++) { h1[i] = (byte) (h1[i] ^ h2[i]); } return bytesToHexString(h1); } public static MessageDigest createDigester() { try { return MessageDigest.getInstance(ALGORITHM); } catch (NoSuchAlgorithmException ex) { throw new PaulException("Can't find the required secure hash algorithm", ex); } } public static String fileHash(File source) throws FileNotFoundException, IOException { try (FileInputStream fis = new FileInputStream(source)) { MessageDigest md = HashUtils.createDigester(); byte[] data = new byte[8192]; int count; while ((count = fis.read(data)) > 0) { md.update(data, 0, count); } byte[] hash = md.digest(); return HashUtils.bytesToHexString(hash); } } }