Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.36 KB | None | 0 0
  1. #include <iomanip>
  2. #include <iostream>
  3. #include <istream>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include <string>
  7.  
  8. #include <openssl\gost.h>
  9. #include <openssl\md4.h>
  10. #include <openssl\md5.h>
  11. #include <openssl\ripemd.h>
  12. #include <openssl\sha.h>
  13. #include <openssl\sm3.h>
  14. #include <openssl\whrlpool.h>
  15.  
  16. class HasherInterface {
  17. public:
  18. typedef unsigned char byte;
  19.  
  20. HasherInterface() {}
  21. virtual ~HasherInterface() {}
  22.  
  23. virtual size_t getDigestLength() = 0;
  24. virtual const char* getAlgoName() = 0;
  25.  
  26. virtual const byte* getHexDigest() = 0;
  27.  
  28. virtual const std::string& getStrDigest() = 0;
  29. virtual operator const std::string& () { return getStrDigest(); }
  30.  
  31. virtual void print() {
  32. std::cout << getAlgoName() << ": " << getStrDigest() << std::endl;
  33. }
  34.  
  35. friend std::ostream& operator<<(std::ostream& os, HasherInterface& hasher) {
  36. os << hasher.getStrDigest();
  37. return os;
  38. }
  39. };
  40.  
  41. template<
  42. const char* algo,
  43. typename Ctx,
  44. int(*initFct)(Ctx *),
  45. int(*updateFct)(Ctx *, const void*, size_t),
  46. int(*finalFct)(unsigned char *,Ctx *),
  47. size_t digestLen
  48. >
  49. class Hasher : public HasherInterface{
  50. private:
  51. Ctx ctx;
  52. byte hexDigest[digestLen];
  53. std::string strDigest;
  54. bool alreadyCalculated;
  55.  
  56. void updateCtx(std::istream& is) {
  57. if(!is) { throw std::runtime_error("The input stream is not initialized."); }
  58. std::streampos currPos = is.tellg();
  59. is.seekg(0, is.end);
  60. size_t length = static_cast<size_t>(is.tellg() - currPos);
  61. if(length) {
  62. is.seekg(currPos);
  63. char* buf = new char[length];
  64. is.read(buf, length);
  65. if(!updateFct(&ctx, reinterpret_cast<unsigned char*>(buf), length)) {
  66. delete buf;
  67. throw std::runtime_error("Impossible to update the hash.");
  68. }
  69. delete buf;
  70. }
  71. }
  72.  
  73. void closeCtx() {
  74. if(!alreadyCalculated) {
  75. unsigned char* ucDigest = reinterpret_cast<unsigned char*>(&hexDigest[0]);
  76. if(!finalFct(ucDigest, &ctx)) {
  77. throw std::runtime_error("Impossible to close the hashing context.");
  78. }
  79. alreadyCalculated = true;
  80. }
  81. }
  82.  
  83. void hex2str() {
  84. closeCtx();
  85. std::ostringstream oss;
  86. for(size_t inc = 0; inc < digestLen; ++inc) {
  87. oss << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(hexDigest[inc]);
  88. }
  89. strDigest = oss.str();
  90. }
  91.  
  92. public:
  93. Hasher(std::istream& is) :
  94. HasherInterface(),
  95. ctx(),
  96. strDigest(),
  97. alreadyCalculated(false) {
  98. memset(hexDigest, 0x00, digestLen * sizeof(byte));
  99. if(!initFct(&ctx)) { throw std::runtime_error("Impossible to initialize the hashing context."); }
  100. updateCtx(is);
  101. }
  102.  
  103. ~Hasher() {}
  104.  
  105. size_t getDigestLength() { return digestLen; }
  106. const char* getAlgoName() { return algo; }
  107.  
  108. const byte* getHexDigest() {
  109. closeCtx();
  110. return hexDigest;
  111. }
  112.  
  113. const std::string& getStrDigest() {
  114. hex2str();
  115. return strDigest;
  116. }
  117.  
  118. friend std::istream& operator>>(std::istream& is, Hasher& hasher) {
  119. hasher.update(is);
  120. return is;
  121. }
  122. };
  123.  
  124. #define TYPEDEF_HASHER_FULL(algo, ctx, fctPrep, digLen, type) \
  125. extern const char algo ## _ALGO_NAME[] = #algo; \
  126. typedef Hasher<algo ## _ALGO_NAME, ctx, fctPrep ## _Init, fctPrep ## _Update, fctPrep ## _Final, digLen> type
  127.  
  128. #define TYPEDEF_HASHER(algo, type) \
  129. extern const char algo ## _ALGO_NAME[] = #algo; \
  130. typedef Hasher<algo ## _ALGO_NAME, algo ## _CTX, algo ## _Init, algo ## _Update, algo ## _Final, algo ## _DIGEST_LENGTH> type
  131.  
  132. TYPEDEF_HASHER(MD4, MD4Hasher);
  133. TYPEDEF_HASHER(MD5, MD5Hasher);
  134. TYPEDEF_HASHER(RIPEMD160, RIPEMD160Hasher);
  135. TYPEDEF_HASHER_FULL(SHA1, SHA_CTX, SHA1, SHA_DIGEST_LENGTH, SHA1Hasher);
  136. TYPEDEF_HASHER_FULL(SHA224, SHA256_CTX, SHA224, SHA224_DIGEST_LENGTH, SHA224Hasher);
  137. TYPEDEF_HASHER(SHA256, SHA256Hasher);
  138. TYPEDEF_HASHER_FULL(SHA384, SHA512_CTX, SHA384, SHA384_DIGEST_LENGTH, SHA384Hasher);
  139. TYPEDEF_HASHER(SHA512, SHA512Hasher);
  140. TYPEDEF_HASHER(SM3, SM3Hasher);
  141. TYPEDEF_HASHER_FULL(STREEBOG256, STREEBOG_CTX, STREEBOG256, STREEBOG256_LENGTH, STREEBOG256Hasher);
  142. TYPEDEF_HASHER_FULL(STREEBOG512, STREEBOG_CTX, STREEBOG512, STREEBOG512_LENGTH, STREEBOG512Hasher);
  143. TYPEDEF_HASHER(WHIRLPOOL, WHIRLPOOLHasher);
  144.  
  145. #define PRINT_HASH(algo, is) \
  146. algo ## Hasher(*is).print(); \
  147. is->seekg(0, is->beg)
  148.  
  149. int main() {
  150. std::istringstream iss("Test");
  151. std::istream* is = &iss;
  152.  
  153. std::streampos cinCurrPos = std::cin.tellg();
  154. std::cin.seekg(0, std::cin.end);
  155. size_t cinLen = static_cast<size_t>(std::cin.tellg() - cinCurrPos);
  156. if(cinLen) {
  157. std::cin.seekg(cinCurrPos);
  158. is = &std::cin;
  159. }
  160.  
  161. std::cout << "input: " << is->rdbuf() << std::endl;
  162. is->seekg(0, is->beg);
  163.  
  164. try {
  165. PRINT_HASH(MD4, is);
  166. PRINT_HASH(MD5, is);
  167. PRINT_HASH(RIPEMD160, is);
  168. PRINT_HASH(SHA1, is);
  169. PRINT_HASH(SHA224, is);
  170. PRINT_HASH(SHA256, is);
  171. PRINT_HASH(SHA384, is);
  172. PRINT_HASH(SHA512, is);
  173. PRINT_HASH(SM3, is);
  174. PRINT_HASH(STREEBOG256, is);
  175. PRINT_HASH(STREEBOG512, is);
  176. PRINT_HASH(WHIRLPOOL, is);
  177. }
  178. catch(std::runtime_error& ex) {
  179. std::cerr << ex.what() << std::endl;
  180. return EXIT_FAILURE;
  181. }
  182.  
  183. return EXIT_SUCCESS;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement