/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2004 satoshi akabane(akabane@logical-paradox.org)
 *
 */
package org.logical_paradox.common.security;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

/**
 * メッセージダイジェストを生成するユーティリティ
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.1 $
 */
public class Digester {
	/** サポートしているアルゴリズム - MD5 */
	public static final String MD5 = "md5";
	/** サポートしているアルゴリズム - SHA1 */
	public static final String SHA1 = "sha1";

	/** アルゴリズム */
	private final String algorithm;
	/** ダイジェスターのインスタンスを格納するマップ */
	private static final HashMap digesters = new HashMap();

	/**
	 * コンストラクタ
	 * @param algo アルゴリズム
	 */
	private Digester(String algo) {
		algorithm = algo;
	}
	/**
	 * ダイジェスターのインスタンスを返す
	 * @param algo アルゴリズム
	 * @return ダイジェスター(既に存在する場合は再利用される)
	 */
	public static final Digester getInstance(String algo) {
		synchronized(digesters) {
			Digester d = (Digester)digesters.get(algo);
			if(d == null) {
				d = new Digester(algo);
				digesters.put(algo, d);
			}
			return d;
		}
	}
	/**
	 * ダイジェストを生成する
	 * @param 元のメッセージ
	 * @return 生成されたハッシュ値
	 */
	public String getDigest(String msg) {
		try {
			// MD5メッセージダイジェスト
			MessageDigest md = MessageDigest.getInstance(algorithm);
			md.update(msg.getBytes());
			byte[] digestData = md.digest();

			/*
			 * 指定された文字列をバイト列に変換して，128bitの16進文字列に変換する
			 */
			StringBuffer sb = new StringBuffer();
			for(int i = 0; i < digestData.length; i++) {
				int b = digestData[i] >= 0 ? digestData[i] : digestData[i] + 256;
				if(b < 0x10) {
					sb.append("0");
				}
				sb.append(Integer.toString(b, 16));
			}
			
			return sb.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		}
	}
}
