/*************************************************************************** * * * HashFunction.java * * ------------------- * * date : 16.08.2004 * * copyright : (C) 2004-2008 Distributed and * * Mobile Systems Group * * Lehrstuhl fuer Praktische Informatik * * Universitaet Bamberg * * http://www.uni-bamberg.de/pi/ * * email : sven.kaffille@uni-bamberg.de * * karsten.loesing@uni-bamberg.de * * * * * ***************************************************************************/ /*************************************************************************** * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * A copy of the license can be found in the license.txt file supplied * * with this software or at: http://www.gnu.org/copyleft/gpl.html * * * ***************************************************************************/ package de.uniba.wiai.lspi.chord.service.impl; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import de.uniba.wiai.lspi.chord.data.ID; import de.uniba.wiai.lspi.chord.data.URL; import de.uniba.wiai.lspi.chord.service.Key; /** * Provides a hash function for calculating the hash value out of {@link Key} or * {@link URL} objects. * * @author Karsten Loesing, Sven Kaffille * @version 1.0.5 */ public class HashFunction { /** * Singleton instance of this class. */ private static HashFunction hashFunction = null; /** * Returns the singleton instance of this class. * * @return Singleton instance of HashFunction. * @throws RuntimeException * If there is an internal problem with the specified hash * function of the Java API. */ static HashFunction getHashFunction() { if (hashFunction == null) { try { hashFunction = new HashFunction(MessageDigest.getInstance("SHA-1")); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("No hash function available!", e); } } return hashFunction; } /** * Message digest for calculating hash values. */ private MessageDigest messageDigest; /** * Constructor is hidden and only invoked once by {@link #getHashFunction()}. * * @param digest1 * Message digest for calculating hash values. */ private HashFunction(MessageDigest digest1) { if (digest1 == null) { throw new NullPointerException("Parameter may not be null!"); } this.messageDigest = digest1; } /** * Returns the length of IDs generated by this hash function. * * @return Number of bytes of generated IDs. */ final int getLengthOfIDsInBytes() { return this.messageDigest.getDigestLength(); } /** * Calculates the hash value for a given data Key. * * @param entry * @return ID for the given Key. */ public ID getHashKey(Key entry) { if (entry == null) { throw new IllegalArgumentException( "Parameter entry must not be null!"); } if (entry.getBytes() == null || entry.getBytes().length == 0) { throw new IllegalArgumentException( "Byte representation of Parameter must not be null or have length 0!"); } byte[] testBytes = entry.getBytes(); return this.createID(testBytes); } private final ID createID(byte[] testBytes) { /* * synchronize access to messageDigest, so that messageDigest cannot be * reset by another thread before calculating digest. */ synchronized (this.messageDigest) { this.messageDigest.reset(); this.messageDigest.update(testBytes); return new ID(this.messageDigest.digest()); } } /** * Calculates the hash value for a given URL. * * @param incomingURL * URL of current node which is used to create a pseudo-unique * ID. * @return ID for the given URL. * @throws IllegalArgumentException * If <code>incomingURL</code> is null! */ final ID createUniqueNodeID(URL incomingURL) { if (incomingURL == null) { throw new IllegalArgumentException("URL must not be null!"); } String id = incomingURL.toString(); ID resultKey = this.createID(id.getBytes()); return resultKey; } }