import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/**
 * Programm zum Entschlüsseln von Hashwerten.
 * 
 * @author André
 *
 */
public class Decrypt {

	/**
	 * 
	 * @param hash
	 *            Hashwert, der zu entschlüsseln ist.
	 * @throws NoSuchAlgorithmException
	 */
	private static final void decrypt(final String hash) throws NoSuchAlgorithmException {
		for (int counter = 0;; counter++) {
			if (calculate_MD5(counter + "").equals(hash)) {
				System.out.printf("Der Hash wurde entschlüsselt! Das Passwort lautet %s\n", counter + "");
				break;
			}
		}
	}

	/**
	 * 
	 * @param to_hash
	 *            Nachricht, die es zu hashen gilt.
	 * @return 128-Bit Hashwert (als Folge von 32 Hexadezimalzahlen).
	 * @throws NoSuchAlgorithmException
	 */
	private static final String calculate_MD5(final String to_hash) throws NoSuchAlgorithmException {
		// MessageDigest-Instanz mit MD5-Algorithmus zuweisen.
		final MessageDigest encrypter = MessageDigest.getInstance("MD5");
		encrypter.reset();
		encrypter.update(to_hash.getBytes());
		final byte[] digest = encrypter.digest();
		BigInteger b_int = new BigInteger(1, digest);
		// Hash als String zurückgeben.
		return b_int.toString(16);
	}

	/**
	 * 
	 * @param hash
	 *            Hashwert, für den das Passwort gefunden werden soll.
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchProviderException
	 */
	public static void main(final String... hash) throws NoSuchAlgorithmException, NoSuchProviderException {
		final long start = System.currentTimeMillis();
		decrypt(hash[0]);
		System.out.printf("Das Programm hat gerade einmal %f Sekunden zum Knacken benötigt:-)\n", (System.currentTimeMillis() - start)/1_000.0);
	}
}