Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iomanip>
- #include <iostream>
- #include <istream>
- #include <sstream>
- #include <stdexcept>
- #include <string>
- #include <openssl\gost.h>
- #include <openssl\md4.h>
- #include <openssl\md5.h>
- #include <openssl\ripemd.h>
- #include <openssl\sha.h>
- #include <openssl\sm3.h>
- #include <openssl\whrlpool.h>
- class HasherInterface {
- public:
- typedef unsigned char byte;
- HasherInterface() {}
- virtual ~HasherInterface() {}
- virtual size_t getDigestLength() = 0;
- virtual const char* getAlgoName() = 0;
- virtual const byte* getHexDigest() = 0;
- virtual const std::string& getStrDigest() = 0;
- virtual operator const std::string& () { return getStrDigest(); }
- virtual void print() {
- std::cout << getAlgoName() << ": " << getStrDigest() << std::endl;
- }
- friend std::ostream& operator<<(std::ostream& os, HasherInterface& hasher) {
- os << hasher.getStrDigest();
- return os;
- }
- };
- template<
- const char* algo,
- typename Ctx,
- int(*initFct)(Ctx *),
- int(*updateFct)(Ctx *, const void*, size_t),
- int(*finalFct)(unsigned char *,Ctx *),
- size_t digestLen
- >
- class Hasher : public HasherInterface{
- private:
- Ctx ctx;
- byte hexDigest[digestLen];
- std::string strDigest;
- bool alreadyCalculated;
- void updateCtx(std::istream& is) {
- if(!is) { throw std::runtime_error("The input stream is not initialized."); }
- std::streampos currPos = is.tellg();
- is.seekg(0, is.end);
- size_t length = static_cast<size_t>(is.tellg() - currPos);
- if(length) {
- is.seekg(currPos);
- char* buf = new char[length];
- is.read(buf, length);
- if(!updateFct(&ctx, reinterpret_cast<unsigned char*>(buf), length)) {
- delete buf;
- throw std::runtime_error("Impossible to update the hash.");
- }
- delete buf;
- }
- }
- void closeCtx() {
- if(!alreadyCalculated) {
- unsigned char* ucDigest = reinterpret_cast<unsigned char*>(&hexDigest[0]);
- if(!finalFct(ucDigest, &ctx)) {
- throw std::runtime_error("Impossible to close the hashing context.");
- }
- alreadyCalculated = true;
- }
- }
- void hex2str() {
- closeCtx();
- std::ostringstream oss;
- for(size_t inc = 0; inc < digestLen; ++inc) {
- oss << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(hexDigest[inc]);
- }
- strDigest = oss.str();
- }
- public:
- Hasher(std::istream& is) :
- HasherInterface(),
- ctx(),
- strDigest(),
- alreadyCalculated(false) {
- memset(hexDigest, 0x00, digestLen * sizeof(byte));
- if(!initFct(&ctx)) { throw std::runtime_error("Impossible to initialize the hashing context."); }
- updateCtx(is);
- }
- ~Hasher() {}
- size_t getDigestLength() { return digestLen; }
- const char* getAlgoName() { return algo; }
- const byte* getHexDigest() {
- closeCtx();
- return hexDigest;
- }
- const std::string& getStrDigest() {
- hex2str();
- return strDigest;
- }
- friend std::istream& operator>>(std::istream& is, Hasher& hasher) {
- hasher.update(is);
- return is;
- }
- };
- #define TYPEDEF_HASHER_FULL(algo, ctx, fctPrep, digLen, type) \
- extern const char algo ## _ALGO_NAME[] = #algo; \
- typedef Hasher<algo ## _ALGO_NAME, ctx, fctPrep ## _Init, fctPrep ## _Update, fctPrep ## _Final, digLen> type
- #define TYPEDEF_HASHER(algo, type) \
- extern const char algo ## _ALGO_NAME[] = #algo; \
- typedef Hasher<algo ## _ALGO_NAME, algo ## _CTX, algo ## _Init, algo ## _Update, algo ## _Final, algo ## _DIGEST_LENGTH> type
- TYPEDEF_HASHER(MD4, MD4Hasher);
- TYPEDEF_HASHER(MD5, MD5Hasher);
- TYPEDEF_HASHER(RIPEMD160, RIPEMD160Hasher);
- TYPEDEF_HASHER_FULL(SHA1, SHA_CTX, SHA1, SHA_DIGEST_LENGTH, SHA1Hasher);
- TYPEDEF_HASHER_FULL(SHA224, SHA256_CTX, SHA224, SHA224_DIGEST_LENGTH, SHA224Hasher);
- TYPEDEF_HASHER(SHA256, SHA256Hasher);
- TYPEDEF_HASHER_FULL(SHA384, SHA512_CTX, SHA384, SHA384_DIGEST_LENGTH, SHA384Hasher);
- TYPEDEF_HASHER(SHA512, SHA512Hasher);
- TYPEDEF_HASHER(SM3, SM3Hasher);
- TYPEDEF_HASHER_FULL(STREEBOG256, STREEBOG_CTX, STREEBOG256, STREEBOG256_LENGTH, STREEBOG256Hasher);
- TYPEDEF_HASHER_FULL(STREEBOG512, STREEBOG_CTX, STREEBOG512, STREEBOG512_LENGTH, STREEBOG512Hasher);
- TYPEDEF_HASHER(WHIRLPOOL, WHIRLPOOLHasher);
- #define PRINT_HASH(algo, is) \
- algo ## Hasher(*is).print(); \
- is->seekg(0, is->beg)
- int main() {
- std::istringstream iss("Test");
- std::istream* is = &iss;
- std::streampos cinCurrPos = std::cin.tellg();
- std::cin.seekg(0, std::cin.end);
- size_t cinLen = static_cast<size_t>(std::cin.tellg() - cinCurrPos);
- if(cinLen) {
- std::cin.seekg(cinCurrPos);
- is = &std::cin;
- }
- std::cout << "input: " << is->rdbuf() << std::endl;
- is->seekg(0, is->beg);
- try {
- PRINT_HASH(MD4, is);
- PRINT_HASH(MD5, is);
- PRINT_HASH(RIPEMD160, is);
- PRINT_HASH(SHA1, is);
- PRINT_HASH(SHA224, is);
- PRINT_HASH(SHA256, is);
- PRINT_HASH(SHA384, is);
- PRINT_HASH(SHA512, is);
- PRINT_HASH(SM3, is);
- PRINT_HASH(STREEBOG256, is);
- PRINT_HASH(STREEBOG512, is);
- PRINT_HASH(WHIRLPOOL, is);
- }
- catch(std::runtime_error& ex) {
- std::cerr << ex.what() << std::endl;
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement