#ifndef HASH_H_INCLUDED
#define HASH_H_INCLUDED

#include <crypto/crypto.h>

class HASH
{
 public:
	const int chainlen;
	const int blocklen;
	const int outlen;

	virtual ostring eval(const ostring& str) = 0;
	virtual void PrettyPrint(std::ostream&) = 0;

	HASH(int c, int b, int o) : chainlen(c), blocklen(b), outlen(o) 
	{
		if(outlen < 1 || outlen > chainlen)
			throw General_error();
	};
};


class SHA1 : public HASH
{
 public:
	ostring eval(const ostring& str);
	void PrettyPrint(std::ostream&);
	SHA1(int len = SHA1_DIGEST_SIZE) 
		: HASH(SHA1_DIGEST_SIZE, SHA1_DATA_SIZE, len) {}
};


class SHA256 : public HASH
{
 public:
        ostring eval(const ostring& str);
	void PrettyPrint(std::ostream&);
        SHA256(int len = SHA256_DIGEST_SIZE)
                : HASH(SHA256_DIGEST_SIZE, SHA256_DATA_SIZE, len) {}
};


class MD5 : public HASH
{
 public:
	ostring eval(const ostring& str);
	void PrettyPrint(std::ostream&);
	MD5(int len = MD5_DIGEST_SIZE) 
		: HASH(MD5_DIGEST_SIZE, MD5_DATA_SIZE, len) {}
};

#endif /* HASH_H_INCLUDED */

