/*
 *  Copyright 2011 Eric F. Savage, code@efsavage.com
 *
 *   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 com.ajah.util.crypto;

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

/**
 * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a
 *         href="mailto:code@efsavage.com">code@efsavage.com</a>.
 * 
 */
public class HashUtils {

	public static String sha1Hex(final String string) {
		try {
			final MessageDigest md = MessageDigest.getInstance("SHA-1");
			byte[] bytes = new byte[40];
			md.update(string.getBytes("iso-8859-1"), 0, string.length());
			bytes = md.digest();
			return String.format("%0" + (bytes.length << 1) + "x", new BigInteger(1, bytes));
		} catch (final NoSuchAlgorithmException e) {
			throw new UnsupportedOperationException(e);
		} catch (final UnsupportedEncodingException e) {
			throw new UnsupportedOperationException(e);
		}
	}

	public static String md5Hex(final String string) {
		try {
			final MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] bytes = new byte[32];
			md.update(string.getBytes("iso-8859-1"), 0, string.length());
			bytes = md.digest();
			return String.format("%0" + (bytes.length << 1) + "x", new BigInteger(1, bytes));
		} catch (final NoSuchAlgorithmException e) {
			throw new UnsupportedOperationException(e);
		} catch (final UnsupportedEncodingException e) {
			throw new UnsupportedOperationException(e);
		}
	}

}

/*
 *  Copyright 2011 Eric F. Savage, code@efsavage.com
 *
 *   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 com.ajah.util.crypto;

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

/**
 * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a
 *         href="mailto:code@efsavage.com">code@efsavage.com</a>.
 * 
 */
public class HashUtils {

	/**
	 * Creates a SHA-1 digest of string and returns it as a hexadecimal number.
	 * 
	 * @param string
	 *            The string to digest.
	 * @return The hexadecimal result of the digest.
	 */
	public static String sha1Hex(final String string) {
		try {
			final MessageDigest md = MessageDigest.getInstance("SHA-1");
			byte[] bytes = new byte[40];
			md.update(string.getBytes("iso-8859-1"), 0, string.length());
			bytes = md.digest();
			return String.format("%0" + (bytes.length << 1) + "x", new BigInteger(1, bytes));
		} catch (final NoSuchAlgorithmException e) {
			throw new UnsupportedOperationException(e);
		} catch (final UnsupportedEncodingException e) {
			throw new UnsupportedOperationException(e);
		}
	}

	/**
	 * Creates an MD5 digest of string and returns it as a hexadecimal number.
	 * 
	 * @param string
	 *            The string to digest.
	 * @return The hexadecimal result of the digest.
	 */
	public static String md5Hex(final String string) {
		try {
			final MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] bytes = new byte[32];
			md.update(string.getBytes("iso-8859-1"), 0, string.length());
			bytes = md.digest();
			return String.format("%0" + (bytes.length << 1) + "x", new BigInteger(1, bytes));
		} catch (final NoSuchAlgorithmException e) {
			throw new UnsupportedOperationException(e);
		} catch (final UnsupportedEncodingException e) {
			throw new UnsupportedOperationException(e);
		}
	}

	/**
	 * Calls {@link #getHashedFileName(String, int, int)} with depth of 3 and
	 * breadth of 2, which should provide enough separation for most
	 * applications.
	 * 
	 * @param name
	 *            The name to hash.
	 * @return The hashed name with directory path.
	 */
	public static String getHashedFileName(final String name) {
		return getHashedFileName(name, 3, 2);
	}

	/**
	 * Creates a hashed name with directory path for a given name.
	 * 
	 * Example: abcdefghijklmnop with depth of 3 and breadth of 2 would return
	 * "ab/cd/ef/abcdefghijklmnop". Example: abcdefghijklmnop with depth of 2
	 * and breadth of 5 would return "abcde/efghi/abcdefghijklmnop".
	 * 
	 * @param name
	 *            The name to hash.
	 * @param depth
	 *            The number of subdirectories to split. A higher number will
	 *            yield more directories but fewer files within each directory.
	 * @param breadth
	 *            The number of characters to use when creating the
	 *            subdirectories. A higher number will yield fewer directories
	 *            but more files within each directory.
	 * @return The hashed name with directory path.
	 */
	public static String getHashedFileName(final String name, final int depth, final int breadth) {
		final StringBuilder hashed = new StringBuilder();
		for (int i = 0; i < depth; i++) {
			hashed.append(name.substring(i * breadth, (i + 1) * breadth));
			hashed.append("/");
		}
		hashed.append(name);
		return hashed.toString();
	}

}

Add getHashedFileName method