From bd0b7e0d895c7f6b43600e91cb1b1d3169196554 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Sat, 3 Dec 2022 13:19:08 -0500
Subject: [PATCH 01/56] Update README to reflect changes.
---
README.md | 49 ++++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/README.md b/README.md
index 85294d6..15add65 100644
--- a/README.md
+++ b/README.md
@@ -6,18 +6,19 @@
Hash++ is a C++17 header-only library that allows a user to retrieve multiple types of hashes from data, files, and files in nested directories. The original purpose behind this library was to create a header-file only implementation of multiple different hash algorithms. You can find a list of the currently supported hash algorithms below.
Supported Algorithms
-
- - MD5
- - MD4
- - MD2
- - SHA-1
- - SHA2-224
- - SHA2-256
- - SHA2-384
- - SHA2-512
- - SHA2-512/224
- - SHA2-512/256
-
+
+| Algorithm | HMAC Support? |
+| :-------------: | :-----------------: |
+| MD5 | :heavy_check_mark: |
+| MD4 | :heavy_check_mark: |
+| MD2 | :heavy_check_mark: |
+| SHA1 | :heavy_check_mark: |
+| SHA2-224 | :heavy_check_mark: |
+| SHA2-256 | :heavy_check_mark: |
+| SHA2-384 | :heavy_check_mark: |
+| SHA2-512 | :heavy_check_mark: |
+| SHA2-512/224 | :heavy_check_mark: |
+| SHA2-512/256 | :heavy_check_mark: |
Hash++ also aims to be a suitable alternative to heavier, statically and dynamically-linked libraries such as OpenSSL and Crypto++. I created it keeping in mind the mindset of a programmer who simply wants a header-only file that lets them easily and comfortably "just hash sh*t." Does it really have to be that difficult?
@@ -33,7 +34,7 @@ No, it doesn't.
|------------------|---------------------------------------------|
| 64-bit test: | | | |
| [MD5] | 7846 ms | 7.846 s | 1,274,535 hashes/s |
-| [MD4] | 5783 ms | 5.783 s | 1,729,206 hashes/s |
+| [MD4] | 7846 ms | 7.846 s | 1,274,535 hashes/s |
| [MD2] | 181315 ms | 181.315 s | 55,153 hashes/s |
| [SHA1] | 8676 ms | 8.676 s | 1,152,605 hashes/s |
| [SHA2-224] | 12370 ms | 12.370 s | 808,407 hashes/s |
@@ -99,23 +100,25 @@ Below you can find the signatures of the only functions necessary to acco
You can find examples of Hash++ in use in the /examples and /tests directories.
-getHash
-Retrieve a single hash from a single piece of data.
+getHash(...), getHMAC(...)
+Retrieve a single hash from a single piece of data, or retrieve an HMAC from a key-data pair.
```cpp
-// function to return a resulting hash from selected ALGORITHM and passed data
-static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data)
+static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data);
+static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data)
```
-getHashes
-Retrieve a collection of hashes from multiple pieces of data.
+getHashes(...), getHMACs(...)
+Retrieve a collection of hashes from multiple pieces of data, or retrieve a collection of HMACs from multiple pieces of data.
```cpp
-// function to return a collection of resulting hashes from selected ALGORITHMS and passed data
-static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs)
+static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs);
+template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data);
+static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs);
+template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data)
```
-getFileHash
+getFileHash(...)
Retrieve a single hash from a single file.
```cpp
@@ -123,7 +126,7 @@ Retrieve a single hash from a single file.
static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path)
```
-getFilesHashes
+getFilesHashes(...)
Retrieve a collection of hashes from multiple files or files in nested directories.
```cpp
From bf43ed704f3431de4130eb46c4ae9aa3ba3f6d60 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Sat, 3 Dec 2022 13:28:58 -0500
Subject: [PATCH 02/56] Add new features.
- Add HMAC implementation for all hash algorithms.
- Add various overloads for existing functions and new HMAC-related functions.
- Add HMAC testing functions to optional metrics class.
See file for more.
---
include/hashpp.h | 1184 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 1176 insertions(+), 8 deletions(-)
diff --git a/include/hashpp.h b/include/hashpp.h
index 1c99a67..a8208a0 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -164,18 +164,38 @@ namespace hashpp {
return this->bytesToHexString();
}
+ std::string getHMAC(std::string key, std::string data) {
+ return this->HMAC(key, data);
+ }
+
protected:
// virtual functions to be overridden by each algorithm implementation.
virtual std::vector getBytes() = 0;
virtual void ctx_init() = 0;
virtual void ctx_update(const uint8_t*, size_t) = 0;
- virtual void ctx_final() = 0;
+ virtual void ctx_final() = 0;
+
+ // H as defined in https://www.rfc-editor.org/rfc/rfc2104 for
+ // Keyed-Hashing for Message Authentication
+ virtual std::string _H(const std::string&, const std::string&) = 0;
+ virtual std::string HMAC(const std::string&, const std::string&) = 0;
+
+ // Helper function to convert hex string to bytes and return them in a vector
+ std::vector fromHex(const std::string& hex) {
+ std::vector bytes;
+ for (size_t i = 0; i < hex.length(); i += 2) {
+ std::string byteString = hex.substr(i, 2);
+ uint8_t byte = static_cast(strtol(byteString.c_str(), NULL, 16));
+ bytes.push_back(byte);
+ }
+ return bytes;
+ }
private:
std::string bytesToHexString() {
const std::vector digest = this->getBytes();
std::string hash;
-
+
for (const auto& d : digest) {
hash += this->hexTable[d];
}
@@ -194,6 +214,8 @@ namespace hashpp {
// private members
private:
+ const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 16;
+
typedef struct {
uint64_t size;
uint32_t buf[4];
@@ -242,6 +264,30 @@ namespace hashpp {
const uint32_t B = 0xefcdab89;
const uint32_t C = 0x98badcfe;
const uint32_t D = 0x10325476;
+
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
// private class methods
private:
@@ -251,6 +297,9 @@ namespace hashpp {
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
// auxiliary functions defined by the algorithm
// as per: https://en.wikipedia.org/wiki/MD5#Algorithm
constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D);
@@ -266,6 +315,8 @@ namespace hashpp {
// private members
private:
+ const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 16;
+
typedef struct {
uint64_t size;
uint32_t buf[4];
@@ -311,6 +362,30 @@ namespace hashpp {
const uint32_t C = 0x98badcfe;
const uint32_t D = 0x10325476;
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
// private class methods
private:
// initialize our context for this hash function
@@ -319,6 +394,9 @@ namespace hashpp {
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
// auxiliary functions defined by the algorithm
// as per: http://practicalcryptography.com/hashes/md4-hash/
constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D);
@@ -338,6 +416,8 @@ namespace hashpp {
// private members
private:
+ const uint8_t BLOCK_SIZE = 16, DIGEST_SIZE = 16;
+
typedef struct {
uint8_t buf[16], state[48], checksum[16], digest[16];
uint64_t size;
@@ -366,10 +446,25 @@ namespace hashpp {
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
};
// MD5
@@ -467,6 +562,60 @@ namespace hashpp {
this->context.digest[(i * 4) + 3] = static_cast((this->context.buf[i] & 0xFF000000) >> 24);
}
}
+ inline std::string MD5::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string MD5::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint32_t hashpp::MD::MD5::F(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & C) | (~B & D)); }
constexpr uint32_t hashpp::MD::MD5::G(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & D) | (C & ~D)); }
constexpr uint32_t hashpp::MD::MD5::H(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B ^ C ^ D)); }
@@ -561,6 +710,60 @@ namespace hashpp {
this->context.digest[(i * 4) + 3] = static_cast((this->context.buf[i] & 0xFF000000) >> 24);
}
}
+ inline std::string MD4::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string MD4::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint32_t hashpp::MD::MD4::F(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & C) | (~B & D)); }
constexpr uint32_t hashpp::MD::MD4::G(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B & C) | (B & D) | (C & D)); }
constexpr uint32_t hashpp::MD::MD4::H(const uint32_t B, const uint32_t C, const uint32_t D) { return ((B ^ C ^ D)); }
@@ -624,6 +827,60 @@ namespace hashpp {
ctx_transform(this->context.checksum);
memcpy(this->context.digest, this->context.state, 16);
}
+ inline std::string MD2::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string MD2::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
}
// Secure Hash Algorithm (SHA) hash family
@@ -651,6 +908,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 20;
+
typedef struct {
uint32_t state[5], k[4], size;
uint64_t bitsize;
@@ -677,11 +936,38 @@ namespace hashpp {
0xca62c1d6
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
// SHA-1 functions defined by the algorithm
constexpr uint32_t A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D);
constexpr uint32_t B(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D);
@@ -699,6 +985,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 28;
+
typedef struct {
uint32_t state[8];
uint64_t size, bitsize;
@@ -740,11 +1028,38 @@ namespace hashpp {
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
constexpr uint32_t A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D);
constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D);
constexpr uint32_t G(const uint32_t B, const uint32_t C, const uint32_t D);
@@ -763,6 +1078,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 64, DIGEST_SIZE = 32;
+
typedef struct {
uint32_t state[8], size;
uint64_t bitsize;
@@ -804,11 +1121,38 @@ namespace hashpp {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
constexpr uint32_t A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D);
constexpr uint32_t F(const uint32_t B, const uint32_t C, const uint32_t D);
constexpr uint32_t G(const uint32_t B, const uint32_t C, const uint32_t D);
@@ -827,6 +1171,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 48;
+
typedef struct {
uint64_t state[8], count[2];
uint8_t data[128], digest[48];
@@ -871,11 +1217,54 @@ namespace hashpp {
0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C);
constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C);
@@ -893,6 +1282,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 64;
+
typedef struct {
uint64_t state[8], count[2];
uint8_t data[128], digest[64];
@@ -937,11 +1328,54 @@ namespace hashpp {
0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C);
constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C);
@@ -959,6 +1393,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 28;
+
typedef struct {
uint64_t state[8], count[2];
uint8_t data[128], digest[32];
@@ -1003,11 +1439,54 @@ namespace hashpp {
0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C);
constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C);
@@ -1025,6 +1504,8 @@ namespace hashpp {
}
private:
+ const uint8_t BLOCK_SIZE = 128, DIGEST_SIZE = 32;
+
typedef struct {
uint64_t state[8], count[2];
uint8_t data[128], digest[32];
@@ -1069,11 +1550,54 @@ namespace hashpp {
0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
};
+ // the byte 0x36 repeated 'B' times where 'B' => block size
+ std::vector ipad = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+ };
+
+ // the byte 0x5c repeated 'B' times
+ std::vector opad = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+ };
+
inline void ctx_init() override;
inline void ctx_transform(const uint8_t* data);
inline void ctx_update(const uint8_t* data, size_t len) override;
inline void ctx_final() override;
+ inline std::string _H(const std::string& a, const std::string& b) override;
+ inline std::string HMAC(const std::string& key, const std::string& data) override;
+
constexpr uint64_t F(const uint64_t A, const uint64_t B, const uint64_t C);
constexpr uint64_t G(const uint64_t A, const uint64_t B, const uint64_t C);
@@ -1199,6 +1723,60 @@ namespace hashpp {
this->context.digest[L + 16] = (this->context.state[4] >> (24 - L * 8)) & 0x000000ff;
}
}
+ inline std::string SHA1::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA1::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint32_t hashpp::SHA::SHA1::A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D) {
return ((A << 24) + (B << 16) + (C << 8) + (D));
}
@@ -1308,6 +1886,60 @@ namespace hashpp {
this->context.digest[i + 24] = (this->context.state[6] >> (24 - i * 8)) & 0x000000ff;
}
}
+ inline std::string SHA2_224::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA2_224::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint32_t hashpp::SHA::SHA2_224::A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D) {
return ((A << 24) + (B << 16) + (C << 8) + (D));
}
@@ -1418,6 +2050,60 @@ namespace hashpp {
this->context.digest[i + 28] = (this->context.state[7] >> (24 - i * 8)) & 0x000000ff;
}
}
+ inline std::string SHA2_256::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA2_256::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint32_t hashpp::SHA::SHA2_256::A(const uint32_t A, const uint32_t B, const uint32_t C, const uint32_t D) {
return ((A << 24) + (B << 16) + (C << 8) + (D));
}
@@ -1549,6 +2235,60 @@ namespace hashpp {
PU64B(this->context.state[4], this->context.digest, 32);
PU64B(this->context.state[5], this->context.digest, 40);
}
+ inline std::string SHA2_384::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA2_384::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint64_t hashpp::SHA::SHA2_384::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); }
constexpr uint64_t hashpp::SHA::SHA2_384::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); }
constexpr uint64_t hashpp::SHA::SHA2_384::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); }
@@ -1679,6 +2419,60 @@ namespace hashpp {
PU64B(this->context.state[6], this->context.digest, 48);
PU64B(this->context.state[7], this->context.digest, 56);
}
+ inline std::string SHA2_512::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA2_512::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint64_t hashpp::SHA::SHA2_512::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); }
constexpr uint64_t hashpp::SHA::SHA2_512::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); }
constexpr uint64_t hashpp::SHA::SHA2_512::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); }
@@ -1806,6 +2600,60 @@ namespace hashpp {
PU64B(this->context.state[2], this->context.digest, 16);
PU64B(this->context.state[3], this->context.digest, 24);
}
+ inline std::string SHA2_512_224::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA2_512_224::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint64_t hashpp::SHA::SHA2_512_224::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); }
constexpr uint64_t hashpp::SHA::SHA2_512_224::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); }
constexpr uint64_t hashpp::SHA::SHA2_512_224::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); }
@@ -1932,6 +2780,60 @@ namespace hashpp {
PU64B(this->context.state[2], this->context.digest, 16);
PU64B(this->context.state[3], this->context.digest, 24);
}
+ inline std::string SHA2_512_256::_H(const std::string& a, const std::string& b) {
+ return this->getHash(a + b);
+ }
+ inline std::string SHA2_512_256::HMAC(const std::string& key, const std::string& data) {
+ std::array k = { 0 }; std::fill(k.begin(), k.end(), 0x00);
+
+ // (1) append zeros to the end of K to create a B byte string
+ // (e.g., if K is of length 20 bytes and B = 64, then K will be
+ // appended with 44 zero bytes 0x00) where B is the block size
+ if (key.length() > this->BLOCK_SIZE) {
+ // if K is longer than B bytes, reset K to K=H(K)
+ // where K can either be composed of entirely bytes of H(K)
+ // (if H(K) == L [where L => digest]) or the first L bytes of
+ // H(K) (if H(K) != L) followed by the remaining zeros (if H(K) < L)
+ std::vector k_ = this->fromHex(this->getHash(key));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ k[i] = k_[i];
+ }
+ }
+ else {
+ // if K is shorter than B bytes, append zeros to the end of K
+ // until K is B bytes long
+ for (uint32_t i = 0; i < key.length(); ++i) {
+ k[i] = key[i];
+ }
+ }
+
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with ipad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->ipad[i] ^= k[i];
+ }
+
+ // (3) append the stream of data 'data' to the B byte string resulting from step (2)
+ for (uint32_t i = 0; i < data.length(); ++i) {
+ this->ipad.push_back(data[i]);
+ }
+
+ // (4) apply H to the stream generated in step (3)
+ // see step (6)
+
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1) with opad
+ for (uint32_t i = 0; i < this->BLOCK_SIZE; ++i) {
+ this->opad[i] ^= k[i];
+ }
+
+ // (6) append the H result from step (4) to the B byte string resulting from step (5)
+ std::vector h_ = this->fromHex(this->getHash(std::string(this->ipad.begin(), this->ipad.end())));
+ for (uint32_t i = 0; i < this->DIGEST_SIZE; ++i) {
+ this->opad.push_back(h_[i]);
+ }
+
+ // (7) apply H to the stream generated in step (6) and output the result
+ return this->getHash(std::string(this->opad.begin(), this->opad.end()));
+ }
constexpr uint64_t hashpp::SHA::SHA2_512_256::F(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (~A & C)); }
constexpr uint64_t hashpp::SHA::SHA2_512_256::G(const uint64_t A, const uint64_t B, const uint64_t C) { return ((A & B) ^ (A & C) ^ (B & C)); }
constexpr uint64_t hashpp::SHA::SHA2_512_256::SIGMA0(const uint64_t A) { return this->rr64(A, 28) ^ this->rr64(A, 34) ^ this->rr64(A, 39); }
@@ -1957,12 +2859,12 @@ namespace hashpp {
operator std::string() const noexcept { return this->hashStr; }
friend std::ostream& operator<<(std::ostream& _Ostr, const hashpp::hash& object) {
- _Ostr << object.hashStr;
+ _Ostr << object.getString();
return _Ostr;
}
hash& operator=(const hashpp::hash& _rhs) noexcept {
- this->hashStr = _rhs.hashStr;
+ this->hashStr = _rhs.getString();
return *this;
}
@@ -1971,13 +2873,13 @@ namespace hashpp {
return *this;
}
- bool operator==(const hashpp::hash& _rhs) noexcept {
- return _rhs.hashStr == this->hashStr;
+ bool operator==(const hashpp::hash& _rhs) const noexcept {
+ return _rhs.getString() == this->getString();
}
template , int> = 0>
- bool operator==(const _Ty& _rhs) noexcept {
- return _rhs == this->hashStr;
+ bool operator==(const _Ty& _rhs) const noexcept {
+ return _rhs == this->getString();
}
private:
@@ -2106,6 +3008,45 @@ namespace hashpp {
}
}
+ // function to return a resulting HMAC from selected ALGORITHM and passed key-data pair
+ static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data) {
+ switch (algorithm) {
+ case hashpp::ALGORITHMS::MD5: {
+ return { hashpp::MD::MD5().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ return { hashpp::MD::MD4().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ return { hashpp::MD::MD2().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ return { hashpp::SHA::SHA1().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ return { hashpp::SHA::SHA2_224().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ return { hashpp::SHA::SHA2_256().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ return { hashpp::SHA::SHA2_384().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ return { hashpp::SHA::SHA2_512().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ return { hashpp::SHA::SHA2_512_224().getHMAC(key, data) };
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ return { hashpp::SHA::SHA2_512_256().getHMAC(key, data) };
+ }
+ default: {
+ return hashpp::hash();
+ }
+ }
+ }
+
// function to return a collection of resulting hashes from selected ALGORITHMS and passed data
static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
@@ -2171,7 +3112,189 @@ namespace hashpp {
}
};
}
+
+ // function to return a collection of resulting hashes from selected ALGORITHM and passed data
+ template ...>, int> = 0>
+ static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data) {
+ switch (algorithm) {
+ case hashpp::ALGORITHMS::MD5: {
+ std::vector vMD5;
+ (vMD5.push_back(hashpp::MD::MD5().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "MD5", vMD5 }}};
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ std::vector vMD4;
+ (vMD4.push_back(hashpp::MD::MD4().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "MD4", vMD4 }}};
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ std::vector vMD2;
+ (vMD2.push_back(hashpp::MD::MD2().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "MD2", vMD2 }}};
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ std::vector vSHA1;
+ (vSHA1.push_back(hashpp::SHA::SHA1().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA1", vSHA1 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ std::vector vSHA2_224;
+ (vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA2-224", vSHA2_224 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ std::vector vSHA2_256;
+ (vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA2-256", vSHA2_256 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ std::vector vSHA_384;
+ (vSHA_384.push_back(hashpp::SHA::SHA2_384().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA2-384", vSHA_384 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ std::vector vSHA2_512;
+ (vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA2-512", vSHA2_512 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ std::vector vSHA2_512_224;
+ (vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA2-512-224", vSHA2_512_224 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ std::vector vSHA2_512_256;
+ (vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(static_cast(data))), ...);
+ return hashCollection {{{ "SHA2-512-256", vSHA2_512_256 }}};
+ }
+ }
+ }
+
+ // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data
+ static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+ for (const std::pair>>& twin : algorithmKeyDataPairs) {
+ for (const std::pair& _keyData : twin.second) {
+ switch (twin.first) {
+ case hashpp::ALGORITHMS::MD5: {
+ vMD5.push_back(hashpp::MD::MD5().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ vMD4.push_back(hashpp::MD::MD4().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ vMD2.push_back(hashpp::MD::MD2().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(_keyData.first, _keyData.second));
+ break;
+ }
+ }
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
+ // function to return a collection of resulting HMACs from selected ALGORITHM and passed key-data
+ template ...>, int> = 0>
+ static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data) {
+ switch (algorithm) {
+ case hashpp::ALGORITHMS::MD5: {
+ std::vector vMD5;
+ (vMD5.push_back(hashpp::MD::MD5().getHMAC(key, data)), ...);
+ return hashCollection {{{ "MD5", vMD5 }}};
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ std::vector vMD4;
+ (vMD4.push_back(hashpp::MD::MD4().getHMAC(key, data)), ...);
+ return hashCollection {{{ "MD4", vMD4 }}};
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ std::vector vMD2;
+ (vMD2.push_back(hashpp::MD::MD2().getHMAC(key, data)), ...);
+ return hashCollection {{{ "MD2", vMD2 }}};
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ std::vector vSHA1;
+ (vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA1", vSHA1 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ std::vector vSHA2_224;
+ (vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA2-224", vSHA2_224 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ std::vector vSHA2_256;
+ (vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA2-256", vSHA2_256 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ std::vector vSHA_384;
+ (vSHA_384.push_back(hashpp::SHA::SHA2_384().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA2-384", vSHA_384 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ std::vector vSHA2_512;
+ (vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA2-512", vSHA2_512 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ std::vector vSHA2_512_224;
+ (vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA2-512-224", vSHA2_512_224 }}};
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ std::vector vSHA2_512_256;
+ (vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(key, data)), ...);
+ return hashCollection {{{ "SHA2-512-256", vSHA2_512_256 }}};
+ }
+ }
+ }
+
// function to return a resulting hash from selected ALGORITHM and passed file
static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path) {
if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
@@ -2370,6 +3493,18 @@ namespace hashpp {
}
}
+ // Function to check each algorithm for HMAC correctness
+ void checkAlgorithms_HMAC() const {
+ for (const hashpp::ALGORITHMS& algorithm : this->algorithms) {
+ if (hashpp::get::getHMAC(algorithm, "k", "d").getString() == this->hmac_comparisons[static_cast(algorithm)].first) {
+ std::cout << this->hmac_comparisons[static_cast(algorithm)].second << " HMAC pass." << std::endl;
+ }
+ else {
+ std::cout << this->hmac_comparisons[static_cast(algorithm)].second << " HMAC fail." << std::endl;
+ }
+ }
+ }
+
// Function to measure performance of all hashing algorithms when hashing 10 million
// repetitions of argument 'target.'
void benchmarkAlgorithms(const std::string& target) {
@@ -2389,6 +3524,25 @@ namespace hashpp {
}
}
+ // Function to measure performance of all HMAC hashing algorithms when hashing 10 million
+ // repetitions of argument 'target' with key 'key.'
+ void benchmarkAlgorithms_HMAC(const std::string& key, const std::string& target) {
+ std::cout << "Testing 10m HMAC hashing repetitions of '" << target << "' with key '" << key << "'.\n" << std::endl;
+ for (const hashpp::ALGORITHMS& algorithm : this->algorithms) {
+ if (algorithm == hashpp::ALGORITHMS::MD2 && !IncludeMD2) {
+ continue;
+ }
+ else {
+ this->startTimer();
+ for (uint32_t i = 0; i < 10000000; i++) {
+ hashpp::get::getHMAC(algorithm, key, target);
+ }
+ this->stopTimer();
+ std::cout << this->hmac_comparisons[static_cast(algorithm)].second << ": " << this->getTime().count() << std::endl;
+ }
+ }
+ }
+
// Function to measure performance of all hashing algorithms when hashing a given file
void benchmarkAlgorithms_File(const std::string& path) {
std::cout << "Testing algorithm speeds for hashing of file '" << path << "'.\n" << std::endl;
@@ -2432,6 +3586,20 @@ namespace hashpp {
{ "a8c9aa3f45f2ada72e3ae9278407b4ade221490596c69b27af611dae", "SHA2-512/224" },
{ "9a895196448c0a9daa9769b48f29db5b41cfe2f6f65943a8ef2b8f446e388f7e", "SHA2-512/256" }
};
+
+ // All correct hashes of data 'd' with key 'k' for HMAC comparison
+ const std::vector> hmac_comparisons = {
+ { "7f330edb3a84f317f7ca433d6038ff9a", "MD5" },
+ { "de693e9b565099e8fe8129b3833a702d", "MD4" },
+ { "a10a9e7a2bcfa4cd38d0a1cab3f25816", "MD2" },
+ { "2b90e41e7c0cc8e2f75c02910c3899cc468ba316", "SHA1" },
+ { "c9b7d3a28728c8a0b10dd425247af65e00725f6e5d32131b0c9a4ac1", "SHA2-224" },
+ { "e7ea21c3bcb63a4da3ad78503168d36bdca0be622382ea60a108fad4e4966679", "SHA2-256" },
+ { "48da203588bac88ca21d843f0dd201e15e33fe08a4db11ff4f07d2b62e2e10dee4e55d49612a658a9e5ac2c0a6b8e945", "SHA2-384" },
+ { "75e6621bf12000a13d8dae79fed84aadffbbceaefd36ae061493b34aef6a2988f0fb91b8ba4fef293ed0bd09e6bb7578858b8f2f7f70fe3ca7490d37f655fd38", "SHA2-512" },
+ { "7882112b43ad00ad1a01bc1a8df3745aad04e27a999ceb60da32bb18", "SHA2-512/224" },
+ { "df48fa6a1e87fc2ccdce7a79028b4cd891ce905ebf411898c9aba975f3a2f8ad", "SHA2-512/256" }
+ };
};
#endif
}
From 2f9d0e88865fc04449657b34f60ba94006d683c6 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Sun, 4 Dec 2022 08:19:40 -0500
Subject: [PATCH 03/56] Fix copy parameter that I somehow missed.
Change copy assignment of string parameters in hashpp::common::getHMAC(...) to lvalue cref to avoid copies.
---
include/hashpp.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/hashpp.h b/include/hashpp.h
index a8208a0..6bdd0a6 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -164,7 +164,8 @@ namespace hashpp {
return this->bytesToHexString();
}
- std::string getHMAC(std::string key, std::string data) {
+ // get hexadecimal HMAC from key-data pair
+ std::string getHMAC(const std::string& key, const std::string& data) {
return this->HMAC(key, data);
}
From 5363c619e91a708d9d1f4e0012e51d14654b38f5 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 12:59:34 -0500
Subject: [PATCH 04/56] Apply fixes, functional changes, etc.
- Fixed various template signatures to constrain properly.
- Added an ambiguous base class Container to simplify the function signatures of several getX functions, as well as the process of passing data to them.
- Re-factored getFilesHashes function structure.
- Added both const std::vector and initializer_list overloads for getXs functions.
- Changed hashpp::hash::getString(...) to return a constexpr result.
- Fixed const-correctness errors.
- Added various type aliases for Container: DataContainer, HMAC_DataContainer, FilePathsContainer.
See file for more.
---
include/hashpp.h | 829 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 674 insertions(+), 155 deletions(-)
diff --git a/include/hashpp.h b/include/hashpp.h
index 6bdd0a6..41b19a2 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -67,6 +67,7 @@
#include
#include
#include
+#include
#include
namespace hashpp {
@@ -164,7 +165,7 @@ namespace hashpp {
return this->bytesToHexString();
}
- // get hexadecimal HMAC from key-data pair
+ // get hexadecimal HMAC from key-data pair
std::string getHMAC(const std::string& key, const std::string& data) {
return this->HMAC(key, data);
}
@@ -2856,7 +2857,7 @@ namespace hashpp {
hash(std::string&& hex) noexcept : hashStr(std::move(hex)) {}
bool valid() const noexcept { return !this->hashStr.empty(); }
- std::string getString() const noexcept { return this->hashStr; };
+ constexpr const std::string& getString() const noexcept { return this->hashStr; };
operator std::string() const noexcept { return this->hashStr; }
friend std::ostream& operator<<(std::ostream& _Ostr, const hashpp::hash& object) {
@@ -2865,12 +2866,16 @@ namespace hashpp {
}
hash& operator=(const hashpp::hash& _rhs) noexcept {
- this->hashStr = _rhs.getString();
+ if (this != &_rhs) {
+ this->hashStr = _rhs.getString();
+ }
return *this;
}
hash& operator=(hashpp::hash&& _rhs) noexcept {
- this->hashStr = std::move(_rhs.hashStr);
+ if (this != &_rhs) {
+ this->hashStr = std::move(_rhs.hashStr);
+ }
return *this;
}
@@ -2894,16 +2899,12 @@ namespace hashpp {
//
// for instance, we can get several hashes of several algorithms and print only
// selected algorithms like so:
- // auto allHashes = hashpp::get::getHashes({ {hashpp::ALGORITHMS::MD4, {"data1", "data2"}},
- // {hashpp::ALGORITHMS::MD5, {"data1", "data2"}} });
+ // auto allHashes = hashpp::get::getHashes(ALGORITHMS::MD5, "data1", "data2", "data3", ...);
// for (auto hash : allHashes["MD5"]) {
// std::cout << hash << std::endl;
// }
- // for (auto hash : allHashes["MD4"]) {
- // std::cout << hash << std::endl;
- // }
//
- // ... et cetera, et cetera ...
+ // ... et cetera ...
class hashCollection {
public:
@@ -2948,25 +2949,110 @@ namespace hashpp {
}
};
+ // Ambiguous base container class to simplify original function signatures of getHash(...)-related functions
+ class Container {
+ public: // constructors
+ Container() noexcept = default;
+ Container(const Container& container) noexcept
+ : algorithm(container.algorithm), key(container.key), data(container.data) {}
+ Container(Container&& container) noexcept
+ : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data
+ ) noexcept : algorithm(algorithm), data(data) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data,
+ const std::string& key
+ ) noexcept : algorithm(algorithm), data(data), key(key) {}
+
+ template ...>, int> = 0>
+ Container(
+ ALGORITHMS algorithm,
+ const _Ts&... data
+ ) noexcept : algorithm(algorithm), data({ data... }) {}
+
+ template ..., std::negation>...>, int> = 0>
+ Container(
+ ALGORITHMS algorithm,
+ _Ts&&... data
+ ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {}
+
+ public: // member functions
+ constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; }
+ constexpr const std::string& getKey() const noexcept { return this->key; }
+ constexpr const std::vector& getData() const noexcept { return this->data; }
+ void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; }
+ void setKey(const std::string& key) noexcept { this->key = key; }
+
+ void setData(const std::vector& data) noexcept { this->data = data; }
+ void setData(std::vector&& data) noexcept { this->data = std::move(data); }
+ template void setData(const _Ts&... data) noexcept { this->data = { data... }; }
+ template >...>, int> = 0>
+ void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; }
+
+ void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); }
+ void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); }
+ template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); }
+ template >...>, int> = 0>
+ void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); }
+
+ Container& operator=(const Container& _rhs) noexcept {
+ if (this != &_rhs) {
+ this->algorithm = _rhs.getAlgorithm();
+ this->key = _rhs.getKey();
+ this->data = _rhs.getData();
+ }
+ return *this;
+ }
+
+ Container& operator=(Container&& _rhs) noexcept {
+ if (this != &_rhs) {
+ this->algorithm = _rhs.algorithm;
+ this->key = std::move(_rhs.key);
+ this->data = std::move(_rhs.data);
+ }
+ return *this;
+ }
- // interface class to allow use of static methods to access
- // all algorithm classes and use their functions without
- // the need of several instantiations of each class in
- // the main source code of the user
+ private: // member variables
+ ALGORITHMS algorithm;
+ std::string key;
+
+ // Holds arbitrary data; how this data is defined is determined
+ // by the functions that the container containing said data is passed to.
+ // (e.g., a call to getFilesHashes with a container will treat all data
+ // in it as paths to files to be hashed, and a call to getHashes with
+ // a container will treat all data as generic data to be hashed)
+ std::vector data;
+ };
+ using HMAC_DataContainer = Container;
+ using DataContainer = Container;
+ using FilePathsContainer = Container;
+
+ // interface class to allow use of static methods to access
+ // all algorithm classes and use their functions without
+ // the need of several instantiations of each class in
+ // the main source code of the user
//
- // i.e., if a user wants to pass data to one or several
- // algorithms and get the hash(es), they can do so via:
- // hashpp::get::getHash or hashpp::get::getHashes
+ // i.e., if a user wants to pass data to one or several
+ // algorithms and get the hash(es), they can do so via:
+ // hashpp::get::getHash or hashpp::get::getHashes
//
- // the retrieval of file hashes is also possible via
- // hashpp::get::getFileHash or collectively via
- // hashpp::get::getFileHashes
+ // the retrieval of file hashes is also possible via
+ // hashpp::get::getFileHash or collectively via
+ // hashpp::get::getFileHashes
//
- // all hashpp::get methods return a hashpp::hash or a
- // hashpp::hashCollection object.
+ // all hashpp::get methods return a hashpp::hash or a
+ // hashpp::hashCollection object.
//
- // refer to the class definitions of both hashpp::hash and
- // hashpp::hashCollection for info on how to use them
+ // refer to the class definitions of both hashpp::hash and
+ // hashpp::hashCollection for info on how to use them
class get {
public:
@@ -3048,53 +3134,71 @@ namespace hashpp {
}
}
- // function to return a collection of resulting hashes from selected ALGORITHMS and passed data
- static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs) {
+ // function to return a collection of resulting hashes from passed data containers
+ static hashpp::hashCollection getHashes(const std::vector& dataSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
- for (const std::pair>& twin : algorithmDataPairs) {
- for (const std::string& _data : twin.second) {
- switch (twin.first) {
- case hashpp::ALGORITHMS::MD5: {
- vMD5.push_back(hashpp::MD::MD5().getHash(_data));
- break;
+ for (const DataContainer& dataSet : dataSets) {
+ switch (dataSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(data));
}
- case hashpp::ALGORITHMS::MD4: {
- vMD4.push_back(hashpp::MD::MD4().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(data));
}
- case hashpp::ALGORITHMS::MD2: {
- vMD2.push_back(hashpp::MD::MD2().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(data));
}
- case hashpp::ALGORITHMS::SHA1: {
- vSHA1.push_back(hashpp::SHA::SHA1().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(data));
}
- case hashpp::ALGORITHMS::SHA2_224: {
- vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(data));
}
- case hashpp::ALGORITHMS::SHA2_256: {
- vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(data));
}
- case hashpp::ALGORITHMS::SHA2_384: {
- vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(data));
}
- case hashpp::ALGORITHMS::SHA2_512: {
- vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(data));
}
- case hashpp::ALGORITHMS::SHA2_512_224: {
- vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(data));
}
- case hashpp::ALGORITHMS::SHA2_512_256: {
- vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(_data));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(data));
}
+ break;
}
}
}
@@ -3114,6 +3218,89 @@ namespace hashpp {
};
}
+ static hashpp::hashCollection getHashes(const std::initializer_list& dataSets) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+
+ for (const DataContainer& dataSet : dataSets) {
+ switch (dataSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(data));
+ }
+ break;
+ }
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
// function to return a collection of resulting hashes from selected ALGORITHM and passed data
template ...>, int> = 0>
@@ -3172,53 +3359,71 @@ namespace hashpp {
}
}
- // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data
- static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs) {
+ // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data containers
+ static hashpp::hashCollection getHMACs(const std::vector& keyDataSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
- for (const std::pair>>& twin : algorithmKeyDataPairs) {
- for (const std::pair& _keyData : twin.second) {
- switch (twin.first) {
- case hashpp::ALGORITHMS::MD5: {
- vMD5.push_back(hashpp::MD::MD5().getHMAC(_keyData.first, _keyData.second));
- break;
+ for (const DataContainer& keyDataSet : keyDataSets) {
+ switch (keyDataSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD5.push_back(hashpp::MD::MD5().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::MD4: {
- vMD4.push_back(hashpp::MD::MD4().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD4.push_back(hashpp::MD::MD4().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::MD2: {
- vMD2.push_back(hashpp::MD::MD2().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD2.push_back(hashpp::MD::MD2().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA1: {
- vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA2_224: {
- vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA2_256: {
- vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA2_384: {
- vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA2_512: {
- vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA2_512_224: {
- vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(keyDataSet.getKey(), data));
}
- case hashpp::ALGORITHMS::SHA2_512_256: {
- vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(_keyData.first, _keyData.second));
- break;
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(keyDataSet.getKey(), data));
}
+ break;
}
}
}
@@ -3238,7 +3443,90 @@ namespace hashpp {
};
}
- // function to return a collection of resulting HMACs from selected ALGORITHM and passed key-data
+ static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+
+ for (const DataContainer& keyDataSet : keyDataSets) {
+ switch (keyDataSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD5.push_back(hashpp::MD::MD5().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD4.push_back(hashpp::MD::MD4().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD2.push_back(hashpp::MD::MD2().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
+ // function to return a collection of resulting HMACs from selected ALGORITHM, key, and data
template ...>, int> = 0>
static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data) {
@@ -3341,102 +3629,333 @@ namespace hashpp {
}
// function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support)
- static hashpp::hashCollection getFilesHashes(const std::vector>>& algorithmPathPairs) {
+ static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
- for (const std::pair>& twin : algorithmPathPairs) {
- for (const std::string& _path : twin.second) {
- if (std::filesystem::exists(_path) && std::filesystem::is_regular_file(_path)) {
- switch (twin.first) {
- case hashpp::ALGORITHMS::MD5: {
- vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(_path)));
- break;
+ for (const FilePathsContainer& filePathSet : filePathSets) {
+ switch (filePathSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path)));
}
- case hashpp::ALGORITHMS::MD4: {
- vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(_path)));
- break;
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(item.path()));
+ }
+ }
}
- case hashpp::ALGORITHMS::MD2: {
- vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(_path)));
- break;
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path)));
}
- case hashpp::ALGORITHMS::SHA1: {
- vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(_path)));
- break;
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path()));
+ }
+ }
}
- case hashpp::ALGORITHMS::SHA2_224: {
- vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(_path)));
- break;
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path)));
}
- case hashpp::ALGORITHMS::SHA2_256: {
- vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(_path)));
- break;
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(item.path()));
+ }
+ }
}
- case hashpp::ALGORITHMS::SHA2_384: {
- vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(_path)));
- break;
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path)));
}
- case hashpp::ALGORITHMS::SHA2_512: {
- vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(_path)));
- break;
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(item.path()));
+ }
+ }
}
- case hashpp::ALGORITHMS::SHA2_512_224: {
- vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(_path)));
- break;
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path)));
}
- case hashpp::ALGORITHMS::SHA2_512_256: {
- vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(_path)));
- break;
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(item.path()));
+ }
+ }
}
}
+ break;
}
- else if (std::filesystem::exists(_path) && std::filesystem::is_directory(_path)) {
- for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(_path)) {
- if (item.is_regular_file()) {
- switch (twin.first) {
- case hashpp::ALGORITHMS::MD5: {
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
+ static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+
+ for (const FilePathsContainer& filePathSet : filePathSets) {
+ switch (filePathSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vMD5.push_back(hashpp::MD::MD5().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::MD4: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vMD4.push_back(hashpp::MD::MD4().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::MD2: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vMD2.push_back(hashpp::MD::MD2().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA1: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA1.push_back(hashpp::SHA::SHA1().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA2_224: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA2_256: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA2_384: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA2_512: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA2_512_224: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(item.path()));
- break;
}
- case hashpp::ALGORITHMS::SHA2_512_256: {
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(item.path()));
- break;
}
}
}
}
+ break;
}
}
}
@@ -3454,7 +3973,7 @@ namespace hashpp {
{ "SHA2-512-256", vSHA2_512_256 }
}
};
- }
+ }
};
#if defined(HASHPP_INCLUDE_METRICS)
From 042ef57ea326e953fe91bbe85be39848b10c0872 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:06:42 -0500
Subject: [PATCH 05/56] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 15add65..d6ef0df 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,7 @@ My original design idea behind Hash++ was for it to be simple. This has r
Below you can find the signatures of the only functions necessary to accomplish retrieving hashes from both single or multiple sets of data, files, and files in nested directories. All functions are located in the hashpp
namespace under class get
(hashpp::get
).
-You can find examples of Hash++ in use in the /examples and /tests directories.
+You can find examples of Hash++ in use in the /documentation directory.
getHash(...), getHMAC(...)
Retrieve a single hash from a single piece of data, or retrieve an HMAC from a key-data pair.
From 4cefcf56af8ed50a7504034d753607f0827c891f Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:11:41 -0500
Subject: [PATCH 06/56] Update function signatures.
---
README.md | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index d6ef0df..aa1a9e0 100644
--- a/README.md
+++ b/README.md
@@ -112,24 +112,27 @@ static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key
Retrieve a collection of hashes from multiple pieces of data, or retrieve a collection of HMACs from multiple pieces of data.
```cpp
-static hashpp::hashCollection getHashes(const std::vector>>& algorithmDataPairs);
-template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data);
-static hashpp::hashCollection getHMACs(const std::vector>>>& algorithmKeyDataPairs);
-template static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data)
+static hashpp::hashCollection getHashes(const std::vector& dataSets);
+static hashpp::hashCollection getHashes(const std::initializer_list& dataSets);
+template
+static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data);
+static hashpp::hashCollection getHMACs(const std::vector& keyDataSets);
+static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets);
+template
+static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data);
```
getFileHash(...)
Retrieve a single hash from a single file.
```cpp
-// function to return a resulting hash from selected ALGORITHM and passed file
-static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path)
+static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path);
```
getFilesHashes(...)
Retrieve a collection of hashes from multiple files or files in nested directories.
```cpp
-// function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support)
-static hashpp::hashCollection getFilesHashes(const std::vector>>& algorithmPathPairs)
+static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets);
+static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets);
```
From 8fdbfe33d5827228394fe4560c9a42495b42588b Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:12:39 -0500
Subject: [PATCH 07/56] Delete examples directory
---
examples/getHashFromFile.cpp | 20 ------------
examples/getHashesFromFiles.cpp | 44 -------------------------
examples/getSimpleHash.cpp | 26 ---------------
examples/getSimpleHashes.cpp | 57 ---------------------------------
4 files changed, 147 deletions(-)
delete mode 100644 examples/getHashFromFile.cpp
delete mode 100644 examples/getHashesFromFiles.cpp
delete mode 100644 examples/getSimpleHash.cpp
delete mode 100644 examples/getSimpleHashes.cpp
diff --git a/examples/getHashFromFile.cpp b/examples/getHashFromFile.cpp
deleted file mode 100644
index 7dcbf5f..0000000
--- a/examples/getHashFromFile.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-
- getHashFromFile
- Example to show how to get the hash of a single file.
-
-*/
-
-#include "hashpp.h"
-
-using namespace hashpp;
-
-int main() {
- // get a hash of item1.txt in relative directory folder1
- hash _a = get::getFileHash(ALGORITHMS::MD5, "./folder1/item1.txt");
-
- std::cout << _a << std::endl;
- // or _a.getString()
-
- // output: 4817a091b69d5e89d7d5757e6ce19609 -> ./folder1/item1.txt
-}
diff --git a/examples/getHashesFromFiles.cpp b/examples/getHashesFromFiles.cpp
deleted file mode 100644
index d811a5c..0000000
--- a/examples/getHashesFromFiles.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-
- getHashesFromFiles:
- Example to show how to get the hashes of multiple files in a directory
- or nested directory.
-
- Assume relative path used has structure:
- .
- |--> /folder1
- |--> /folder2
- |-- item6.txt
- |-- item1.txt
- |-- item2.txt
- |-- item3.txt
- |-- item4.txt
- |-- item5.txt
-
- hashpp::get::getFilesHashes() traverses directories and hashes files
- alphabetically.
-
-*/
-
-#include "hashpp.h"
-
-using namespace hashpp;
-
-int main() {
- // get a collection of hashes from files in relative directory folder1 and subsequent dirs
- hashCollection _a = get::getFilesHashes({ {ALGORITHMS::MD5, {"./folder1"}} });
-
- // print each MD5 hash collected
- for (auto _z : _a["MD5"]) {
- std::cout << _z << std::endl;
- }
-
- /* the output is as follows:
- 11ddbaf3386aea1f2974eee984542152 -> ./folder1/folder2/item6.txt
- 4817a091b69d5e89d7d5757e6ce19609 -> ./folder1/item1.txt
- 15cd0e3d368b6a8eb7378dc81ad40dfb -> ./folder1/item2.txt
- e09ab0e2ff8e94687f228eac8a627887 -> ./folder1/item3.txt
- 2995ff3cd4c7d15b529bf3fa76e5cc71 -> ./folder1/item4.txt
- 8188577c8d593f7654c3cc621fdfa009 -> ./folder1/item5.txt
- */
-}
diff --git a/examples/getSimpleHash.cpp b/examples/getSimpleHash.cpp
deleted file mode 100644
index c9a5d62..0000000
--- a/examples/getSimpleHash.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-
- getHash.cpp
- Example showing how to get the hash of simple data.
-
-*/
-
-#include "hashpp.h"
-
-using namespace hashpp;
-
-int main() {
- // string that we want to get the hash of
- std::string dataToBeHashed = "sample text";
-
- // hashes can be printed directly like normal
- // output: bc658c641ef71739fb9995bded59b21150bbff4367f6e4e4c7934b489b9d2c00
- std::cout << get::getHash(ALGORITHMS::SHA2_256, dataToBeHashed) << std::endl;
-
- // ... or, we can capture the returned hashpp::hash object
- hash _hex = get::getHash(ALGORITHMS::SHA2_256, dataToBeHashed);
- std::cout << _hex << std::endl;
-
- // ... or, we can simply capture the std::string object of the hash's hex string
- std::string _hexString = get::getHash(ALGORITHMS::SHA2_256, dataToBeHashed).getString();
-}
diff --git a/examples/getSimpleHashes.cpp b/examples/getSimpleHashes.cpp
deleted file mode 100644
index e7262d4..0000000
--- a/examples/getSimpleHashes.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-
- getSimpleHashes.cpp
- Example showing how to retrieve and iterate several hashes from several pieces of simple data.
-
-*/
-
-#include "hashpp.h"
-
-using namespace hashpp;
-
-int main() {
- // get a hash collection containing the MD5 and MD4 hashes for all passed data
- std::vector data1 = { "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9" };
- std::vector data2 = { "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9" };
- hashCollection collection1 = get::getHashes({ {ALGORITHMS::MD4, data1}, {ALGORITHMS::MD5, data2} });
-
- // the method above of getting multiple hashes is equivalent to the below
- hashCollection collection2 = get::getHashes({ {ALGORITHMS::MD4, {"data1", "data2", "data3",
- "data4", "data5", "data6",
- "data7", "data8", "data9"} },
- {ALGORITHMS::MD5, {"data1", "data2", "data3",
- "data4", "data5", "data6",
- "data7", "data8", "data9"} } });
-
- // to iterate over hashes from a specific algorithm (in the order they were supplied)
- for (auto i : collection2["MD5"]) {
- std::cout << i << std::endl;
- }
- for (auto i : collection2["MD4"]) {
- std::cout << i << std::endl;
- }
-
- // the above will iterate through the hashes of "data1"-"data9" for both MD5 and MD4
- /*
- First iteration (MD5):
- 89d903bc35dede724fd52c51437ff5fd -> data1
- ff9cf2d690d888cb337f6bf4526b6130 -> data2
- 79369f78f7882c1baabbc7d45dc5daa0 -> data3
- 732160808412a20c3f0bfad2b3822d1b -> data4
- cd8e177a28c90b63d548464fa36b2a14 -> data5
- 78c5d69ee9c8aecbf63710a3733501f2 -> data6
- 4a7506e3aa540549299dbf459238f7be -> data7
- c1e739549f7045ca51d24faee4d3f18d -> data8
- fc5f764fd223e02a85787099f2e51431 -> data9
- Second Iteration (MD4):
- 6ae4b3d10b07413e1ea4915f6da7cab4 -> data1
- ce730e5c428c5fd0dc951c90508547fe -> data2
- a4673b83fec1b1ae9eeea7f22a71f86f -> data3
- 2985b2773e43dce3033e38eab9956fc5 -> data4
- 6f818b962e62ad9f406e98efbd65feb4 -> data5
- ecd827c94a72c4e23b7fb39b962ed54a -> data6
- 81847db91976839c31292c83eac2683d -> data7
- 496c47c9f969be38672817cac65bb38d -> data8
- 03ce39fe2914fafebd1bcb81acb816ea -> data9
- */
-}
From e8a254c0f1fe063995eed6feb694c18eabe3c7f9 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:13:17 -0500
Subject: [PATCH 08/56] Delete hashUserSuppliedData.cpp
---
tests/hashUserSuppliedData.cpp | 39 ----------------------------------
1 file changed, 39 deletions(-)
delete mode 100644 tests/hashUserSuppliedData.cpp
diff --git a/tests/hashUserSuppliedData.cpp b/tests/hashUserSuppliedData.cpp
deleted file mode 100644
index a562383..0000000
--- a/tests/hashUserSuppliedData.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-
- Simple program to hash command-line supplied data
- Example:
- ./program.exe data1 data2 data3
-
- output:
- MD5: "data1": 89d903bc35dede724fd52c51437ff5fd
- MD4: "data1": 6ae4b3d10b07413e1ea4915f6da7cab4
- MD2: "data1": 2feff92dc8130b5f4104e430a77269e0
- SHA1: "data1": cbcc2ff6a0894e6e7f9a1a6a6a36b68fb36aa151
- SHA2-224: "data1": 2fa1977e21efb718f7bfa4392e8ff6f9cd07ef2c81e1f0bd5164f8b7
- SHA2-256: "data1": 5b41362bc82b7f3d56edc5a306db22105707d01ff4819e26faef9724a2d406c9
- SHA2-384: "data1": ea77c52d2aab72be97f2864011b11a2d16b07eb67c9dfb9549ac141e2a03369ac59563f5f370a7504f72bccd0ccad31c
- SHA2-512: "data1": 9731b541b22c1d7042646ab2ee17685bbb664bced666d8ecf3593f3ef46493deef651b0f31b6cff8c4df8dcb425a1035e86ddb9877a8685647f39847be0d7c01
- SHA2-512/224: "data1": 42161d4488f6f3d03e4f05f85d6354ed8f211ebdd563ba928c388010
- SHA2-512/256: "data1": b4b134e80ec4b27a0d5ab88c7c466ddfca17ce9f4b4369f83b118bfea09516c0
- ... and so on ...
-
-*/
-
-#include "hashpp.h"
-
-using namespace hashpp;
-
-int main(int argc, const char* argv[]) {
- for (int i = 1; i < argc; i++) {
- std::cout << " MD5: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::MD5, argv[i]) << std::endl;
- std::cout << " MD4: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::MD4, argv[i]) << std::endl;
- std::cout << " MD2: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::MD2, argv[i]) << std::endl;
- std::cout << " SHA1: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA1, argv[i]) << std::endl;
- std::cout << " SHA2-224: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_224, argv[i]) << std::endl;
- std::cout << " SHA2-256: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_256, argv[i]) << std::endl;
- std::cout << " SHA2-384: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_384, argv[i]) << std::endl;
- std::cout << " SHA2-512: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_512, argv[i]) << std::endl;
- std::cout << "SHA2-512/224: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_512_224, argv[i]) << std::endl;
- std::cout << "SHA2-512/256: \"" << argv[i] << "\": " << get::getHash(ALGORITHMS::SHA2_512_256, argv[i]) << std::endl;
- }
-}
From 579bccbf25651a9789a2419aa88088b2ffc851d5 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:13:43 -0500
Subject: [PATCH 09/56] Create documentation README.
---
documentation/README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 documentation/README.md
diff --git a/documentation/README.md b/documentation/README.md
new file mode 100644
index 0000000..c65637d
--- /dev/null
+++ b/documentation/README.md
@@ -0,0 +1 @@
+Add docs here.
From 5e7c61a03cbe77c8bbfe5493d29069ad8446de5f Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:15:50 -0500
Subject: [PATCH 10/56] Create documentation/hashing README.
---
documentation/hashing/README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 documentation/hashing/README.md
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
new file mode 100644
index 0000000..8df3d73
--- /dev/null
+++ b/documentation/hashing/README.md
@@ -0,0 +1 @@
+Add generic hashing docs + examples here
From 33a289b4d5dd10f2f25185d16b34d2aa0b847f3c Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:16:20 -0500
Subject: [PATCH 11/56] Create HMAC documentation README.
---
documentation/HMACs/README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 documentation/HMACs/README.md
diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md
new file mode 100644
index 0000000..c54bdc4
--- /dev/null
+++ b/documentation/HMACs/README.md
@@ -0,0 +1 @@
+Add HMAC documentation + examples here.
From a6c3fcc38402ced7bd1b8b61fde6e1d5506c40f2 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:17:39 -0500
Subject: [PATCH 12/56] Create documentation README for file_hashing.
---
documentation/file_hashing | 1 +
1 file changed, 1 insertion(+)
create mode 100644 documentation/file_hashing
diff --git a/documentation/file_hashing b/documentation/file_hashing
new file mode 100644
index 0000000..5fd4350
--- /dev/null
+++ b/documentation/file_hashing
@@ -0,0 +1 @@
+Add file hashing documentation + examples here.
From 5502cea17fe4dd57dff2ab091ac8585d4f3314f7 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:17:52 -0500
Subject: [PATCH 13/56] Delete file_hashing
---
documentation/file_hashing | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 documentation/file_hashing
diff --git a/documentation/file_hashing b/documentation/file_hashing
deleted file mode 100644
index 5fd4350..0000000
--- a/documentation/file_hashing
+++ /dev/null
@@ -1 +0,0 @@
-Add file hashing documentation + examples here.
From c6b8eb5e3989ad220ec2bf3f5160db62660d7086 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 13:18:34 -0500
Subject: [PATCH 14/56] Create file_hashing README documentation (real)
---
documentation/file_hashing/README.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 documentation/file_hashing/README.md
diff --git a/documentation/file_hashing/README.md b/documentation/file_hashing/README.md
new file mode 100644
index 0000000..5fd4350
--- /dev/null
+++ b/documentation/file_hashing/README.md
@@ -0,0 +1 @@
+Add file hashing documentation + examples here.
From ece1cedae1d17e420b0b750113804b2516e702df Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 17:53:18 -0500
Subject: [PATCH 15/56] Populate base documentation README.
---
documentation/README.md | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/documentation/README.md b/documentation/README.md
index c65637d..473e5c4 100644
--- a/documentation/README.md
+++ b/documentation/README.md
@@ -1 +1,11 @@
-Add docs here.
+Documentation
+Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hased message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data.
+
+In the directories listed below, you can find explanations of concepts found within the implementations of the library and example usage of features found within Hash++.
+
+- Hashing Documentation
+ - Covers basic hashing concepts and how to generate them using the library.
+- HMAC Documentation
+ - Covers basic HMAC concepts and how to generate them using the library.
+- File-hashing Documentation
+ - Covers how to hash files using the library.
From cd18f9670a7036778f4d40c458f00bad61cf59c8 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 17:53:53 -0500
Subject: [PATCH 16/56] Fix typo.
---
documentation/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/documentation/README.md b/documentation/README.md
index 473e5c4..cc13ec7 100644
--- a/documentation/README.md
+++ b/documentation/README.md
@@ -1,5 +1,5 @@
Documentation
-Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hased message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data.
+Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and hashed message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data.
In the directories listed below, you can find explanations of concepts found within the implementations of the library and example usage of features found within Hash++.
From 8680e2e07c0bfde5c3a248c390e9751fdca0da55 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 18:38:01 -0500
Subject: [PATCH 17/56] Update README.md
---
documentation/hashing/README.md | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
index 8df3d73..3c2104f 100644
--- a/documentation/hashing/README.md
+++ b/documentation/hashing/README.md
@@ -1 +1,24 @@
-Add generic hashing docs + examples here
+Hashing
+Hashing, in simple terms, is the cryptographic process of assigning a unique fingerprint to data such that no other data will produce the same fingerprint as another piece of data.
+
+In mathematical terms, hashing is the functional process of mapping any arbitrary data X
to a fixed-size, unique, and seemingly nonsensical value D
. Hashing algorithms are one-way functions such that, given an input x
to some hash function H
, it is facile to compute the output hash digest D
; however, given only some hash function H
and an associated output digest D
, it is infeasible to compute the original input data x
.
+
+Simply, a one-way function H(x) = D
is one such function that satisfies all constraints such that...
+
+- D
is easily computed given x
.
+- H
's output range is known.
+- Given only output D
and function H
, x
is infeasibly computed such that H(x) = D
.
+
+Given this inherent infeasibility of recovering initial input data to a given hash function, they are useful for a number of security purposes such as:
+
+- Message and file integrity verification.
+- Password verification.
+- Signature/identifier generation and verification.
+- Key Derivation Functions (KDFs).
+- Proof-of-Work.
+- Blockchain Technology.
+- Public-Key Cryptography.
+- CSPRNGs.
+
+Using Hash++
+Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above.
From ea6309a1dd4a185c0dedf8491bbc1fb2db0ea3e9 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 18:40:23 -0500
Subject: [PATCH 18/56] Update README.md
---
README.md | 43 +------------------------------------------
1 file changed, 1 insertion(+), 42 deletions(-)
diff --git a/README.md b/README.md
index aa1a9e0..06a58b1 100644
--- a/README.md
+++ b/README.md
@@ -94,45 +94,4 @@ No, it doesn't.
```
Using Hash++
-My original design idea behind Hash++ was for it to be simple. This has remained unchanged.
-
-Below you can find the signatures of the only functions necessary to accomplish retrieving hashes from both single or multiple sets of data, files, and files in nested directories. All functions are located in the hashpp
namespace under class get
(hashpp::get
).
-
-You can find examples of Hash++ in use in the /documentation directory.
-
-getHash(...), getHMAC(...)
-Retrieve a single hash from a single piece of data, or retrieve an HMAC from a key-data pair.
-
-```cpp
-static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data);
-static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data)
-```
-
-getHashes(...), getHMACs(...)
-Retrieve a collection of hashes from multiple pieces of data, or retrieve a collection of HMACs from multiple pieces of data.
-
-```cpp
-static hashpp::hashCollection getHashes(const std::vector& dataSets);
-static hashpp::hashCollection getHashes(const std::initializer_list& dataSets);
-template
-static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data);
-static hashpp::hashCollection getHMACs(const std::vector& keyDataSets);
-static hashpp::hashCollection getHMACs(const std::initializer_list& keyDataSets);
-template
-static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data);
-```
-
-getFileHash(...)
-Retrieve a single hash from a single file.
-
-```cpp
-static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path);
-```
-
-getFilesHashes(...)
-Retrieve a collection of hashes from multiple files or files in nested directories.
-
-```cpp
-static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets);
-static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets);
-```
+You can find detailed documentation in the /documentation directory.
From c58cade8410164505cb8419d808ddf4dca136311 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 18:52:05 -0500
Subject: [PATCH 19/56] Create container.cpp
---
documentation/hashing/container.cpp | 81 +++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
create mode 100644 documentation/hashing/container.cpp
diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp
new file mode 100644
index 0000000..72be7f8
--- /dev/null
+++ b/documentation/hashing/container.cpp
@@ -0,0 +1,81 @@
+ class Container {
+ public: // constructors
+ Container() noexcept = default;
+ Container(const Container& container) noexcept
+ : algorithm(container.algorithm), key(container.key), data(container.data) {}
+ Container(Container&& container) noexcept
+ : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data
+ ) noexcept : algorithm(algorithm), data(data) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data,
+ const std::string& key
+ ) noexcept : algorithm(algorithm), data(data), key(key) {}
+
+ template ...>, int> = 0>
+ Container(
+ ALGORITHMS algorithm,
+ const _Ts&... data
+ ) noexcept : algorithm(algorithm), data({ data... }) {}
+
+ template ..., std::negation>...>, int> = 0>
+ Container(
+ ALGORITHMS algorithm,
+ _Ts&&... data
+ ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {}
+
+ public: // member functions
+ constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; }
+ constexpr const std::string& getKey() const noexcept { return this->key; }
+ constexpr const std::vector& getData() const noexcept { return this->data; }
+ void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; }
+ void setKey(const std::string& key) noexcept { this->key = key; }
+
+ void setData(const std::vector& data) noexcept { this->data = data; }
+ void setData(std::vector&& data) noexcept { this->data = std::move(data); }
+ template void setData(const _Ts&... data) noexcept { this->data = { data... }; }
+ template >...>, int> = 0>
+ void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; }
+
+ void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); }
+ void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); }
+ template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); }
+ template >...>, int> = 0>
+ void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); }
+
+ Container& operator=(const Container& _rhs) noexcept {
+ if (this != &_rhs) {
+ this->algorithm = _rhs.getAlgorithm();
+ this->key = _rhs.getKey();
+ this->data = _rhs.getData();
+ }
+ return *this;
+ }
+
+ Container& operator=(Container&& _rhs) noexcept {
+ if (this != &_rhs) {
+ this->algorithm = _rhs.algorithm;
+ this->key = std::move(_rhs.key);
+ this->data = std::move(_rhs.data);
+ }
+ return *this;
+ }
+
+ private: // member variables
+ ALGORITHMS algorithm;
+ std::string key;
+
+ // Holds arbitrary data; how this data is defined is determined
+ // by the functions that the container containing said data is passed to.
+ // (e.g., a call to getFilesHashes with a container will treat all data
+ // in it as paths to files to be hashed, and a call to getHashes with
+ // a container will treat all data as generic data to be hashed)
+ std::vector data;
+ };
From ff79840060de728177390b2f54716cc4e8d1db30 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 18:53:13 -0500
Subject: [PATCH 20/56] Update container.cpp
---
documentation/hashing/container.cpp | 142 ++++++++++++++--------------
1 file changed, 71 insertions(+), 71 deletions(-)
diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp
index 72be7f8..dca99a3 100644
--- a/documentation/hashing/container.cpp
+++ b/documentation/hashing/container.cpp
@@ -1,81 +1,81 @@
- class Container {
- public: // constructors
- Container() noexcept = default;
- Container(const Container& container) noexcept
- : algorithm(container.algorithm), key(container.key), data(container.data) {}
- Container(Container&& container) noexcept
- : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {}
- Container(
- ALGORITHMS algorithm,
- const std::vector& data
- ) noexcept : algorithm(algorithm), data(data) {}
- Container(
- ALGORITHMS algorithm,
- const std::vector& data,
- const std::string& key
- ) noexcept : algorithm(algorithm), data(data), key(key) {}
-
- template ...>, int> = 0>
- Container(
- ALGORITHMS algorithm,
- const _Ts&... data
- ) noexcept : algorithm(algorithm), data({ data... }) {}
+class Container {
+ public: // constructors
+ Container() noexcept = default;
+ Container(const Container& container) noexcept
+ : algorithm(container.algorithm), key(container.key), data(container.data) {}
+ Container(Container&& container) noexcept
+ : algorithm(container.algorithm), key(std::move(container.key)), data(std::move(container.data)) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data
+ ) noexcept : algorithm(algorithm), data(data) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data,
+ const std::string& key
+ ) noexcept : algorithm(algorithm), data(data), key(key) {}
+
+ template ...>, int> = 0>
+ Container(
+ ALGORITHMS algorithm,
+ const _Ts&... data
+ ) noexcept : algorithm(algorithm), data({ data... }) {}
- template ..., std::negation>...>, int> = 0>
- Container(
- ALGORITHMS algorithm,
- _Ts&&... data
- ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {}
+ template ..., std::negation>...>, int> = 0>
+ Container(
+ ALGORITHMS algorithm,
+ _Ts&&... data
+ ) noexcept : algorithm(algorithm), data({ std::forward<_Ts>(data)... }) {}
- public: // member functions
- constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; }
- constexpr const std::string& getKey() const noexcept { return this->key; }
- constexpr const std::vector& getData() const noexcept { return this->data; }
- void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; }
- void setKey(const std::string& key) noexcept { this->key = key; }
+ public: // member functions
+ constexpr const ALGORITHMS& getAlgorithm() const noexcept { return this->algorithm; }
+ constexpr const std::string& getKey() const noexcept { return this->key; }
+ constexpr const std::vector& getData() const noexcept { return this->data; }
+ void setAlgorithm(ALGORITHMS algorithm) noexcept { this->algorithm = algorithm; }
+ void setKey(const std::string& key) noexcept { this->key = key; }
- void setData(const std::vector& data) noexcept { this->data = data; }
- void setData(std::vector&& data) noexcept { this->data = std::move(data); }
- template void setData(const _Ts&... data) noexcept { this->data = { data... }; }
- template >...>, int> = 0>
- void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; }
+ void setData(const std::vector& data) noexcept { this->data = data; }
+ void setData(std::vector&& data) noexcept { this->data = std::move(data); }
+ template void setData(const _Ts&... data) noexcept { this->data = { data... }; }
+ template >...>, int> = 0>
+ void setData(_Ts&&... data) noexcept { this->data = { std::forward<_Ts>(data)... }; }
- void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); }
- void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); }
- template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); }
- template >...>, int> = 0>
- void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); }
+ void appendData(const std::vector& data) noexcept { this->data.insert(this->data.end(), data.begin(), data.end()); }
+ void appendData(std::vector&& data) noexcept { this->data.insert(this->data.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end())); }
+ template void appendData(const _Ts&... data) noexcept { (this->data.push_back(data), ...); }
+ template >...>, int> = 0>
+ void appendData(_Ts&&... data) noexcept { (this->data.push_back(std::forward<_Ts>(data)), ...); }
- Container& operator=(const Container& _rhs) noexcept {
- if (this != &_rhs) {
- this->algorithm = _rhs.getAlgorithm();
- this->key = _rhs.getKey();
- this->data = _rhs.getData();
- }
- return *this;
+ Container& operator=(const Container& _rhs) noexcept {
+ if (this != &_rhs) {
+ this->algorithm = _rhs.getAlgorithm();
+ this->key = _rhs.getKey();
+ this->data = _rhs.getData();
}
+ return *this;
+ }
- Container& operator=(Container&& _rhs) noexcept {
- if (this != &_rhs) {
- this->algorithm = _rhs.algorithm;
- this->key = std::move(_rhs.key);
- this->data = std::move(_rhs.data);
- }
- return *this;
+ Container& operator=(Container&& _rhs) noexcept {
+ if (this != &_rhs) {
+ this->algorithm = _rhs.algorithm;
+ this->key = std::move(_rhs.key);
+ this->data = std::move(_rhs.data);
}
+ return *this;
+ }
- private: // member variables
- ALGORITHMS algorithm;
- std::string key;
+ private: // member variables
+ ALGORITHMS algorithm;
+ std::string key;
- // Holds arbitrary data; how this data is defined is determined
- // by the functions that the container containing said data is passed to.
- // (e.g., a call to getFilesHashes with a container will treat all data
- // in it as paths to files to be hashed, and a call to getHashes with
- // a container will treat all data as generic data to be hashed)
- std::vector data;
- };
+ // Holds arbitrary data; how this data is defined is determined
+ // by the functions that the container containing said data is passed to.
+ // (e.g., a call to getFilesHashes with a container will treat all data
+ // in it as paths to files to be hashed, and a call to getHashes with
+ // a container will treat all data as generic data to be hashed)
+ std::vector data;
+};
From 2c8e4280291cef5472f41bb2cc00c21e9001fac2 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 19:10:48 -0500
Subject: [PATCH 21/56] Create container_use.cpp
---
documentation/hashing/container_use.cpp | 37 +++++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 documentation/hashing/container_use.cpp
diff --git a/documentation/hashing/container_use.cpp b/documentation/hashing/container_use.cpp
new file mode 100644
index 0000000..81c2074
--- /dev/null
+++ b/documentation/hashing/container_use.cpp
@@ -0,0 +1,37 @@
+/*
+
+ Basic usage and examples of Hash++ container class Container.
+ This container can be used to store paths to files to be hashed,
+ data to be hashed, keys to use in generating HMACs of contained data,
+ the algorithm to use to hash the contained data, etc.
+
+ This container and its aliases are used in several function overloads
+ where a developer may want to pass several sets of data and use a
+ different hashing algorithm for each set of data.
+
+*/
+
+#include "hashpp.h"
+
+using namespace hashpp;
+
+int main() {
+ // instantiation, assignment via member functions
+ DataContainer cont1;
+ cont1.setData("dataToHash1", "dataToHash2");
+ cont1.appendData("moreDataToHash1", "moreDataToHash2");
+ cont1.setAlgorithm(ALGORITHMS::SHA2_224);
+
+ // instantiation, assignment via variadic data constructor
+ DataContainer cont2(ALGORITHMS::SHA2_256, "dataToHash1", "dataToHash2", "moreDataToHash1", "moreDataToHash2");
+
+ // instantiation, assignment via vector constructor
+ std::vector data = { "dataToHash1", "dataToHash2", "moreDataToHash1", "moreDataToHash2" };
+ DataContainer cont3(ALGORITHMS::SHA2_384, data);
+
+ // these containers can then be passed to their respective library function overloads
+ // as an initializer list or vector
+ std::vector containers = { cont1, cont2, cont3 };
+ auto _hashes1 = get::getHashes(containers);
+ auto _hashes2 = get::getHashes({ cont1, cont2, cont3 });
+}
From 1feff88e7ff8d039c077525a7fe87a6646673c48 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 19:19:40 -0500
Subject: [PATCH 22/56] Add more moves cons. for Container
---
include/hashpp.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/include/hashpp.h b/include/hashpp.h
index 41b19a2..706ee2a 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -2961,11 +2961,30 @@ namespace hashpp {
ALGORITHMS algorithm,
const std::vector& data
) noexcept : algorithm(algorithm), data(data) {}
+ Container(
+ ALGORITHMS algorithm,
+ std::vector&& data
+ ) noexcept : algorithm(algorithm), data(std::move(data)) {}
Container(
ALGORITHMS algorithm,
const std::vector& data,
const std::string& key
) noexcept : algorithm(algorithm), data(data), key(key) {}
+ Container(
+ ALGORITHMS algorithm,
+ std::vector&& data,
+ const std::string& key
+ ) noexcept : algorithm(algorithm), data(std::move(data)), key(key) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data,
+ std::string&& key
+ ) noexcept : algorithm(algorithm), data(data), key(std::move(key)) {}
+ Container(
+ ALGORITHMS algorithm,
+ std::vector&& data,
+ std::string&& key
+ ) noexcept : algorithm(algorithm), data(std::move(data)), key(std::move(key)) {}
template ...>, int> = 0>
From 913b164188fdb9efaf543aea1abebf3e9dcf083a Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 19:22:27 -0500
Subject: [PATCH 23/56] Update README.md
---
documentation/hashing/README.md | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
index 3c2104f..4f480cf 100644
--- a/documentation/hashing/README.md
+++ b/documentation/hashing/README.md
@@ -21,4 +21,18 @@ Given this inherent infeasibility of recovering initial input data to a given ha
- CSPRNGs.
Using Hash++
-Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above.
+Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above. You can generate simple hashes using the functions described below.
+
+```
+static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data);
+static hashpp::hashCollection getHashes(const std::vector& dataSets);
+static hashpp::hashCollection getHashes(const std::initializer_list& dataSets);
+template static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data);
+```
+
+Some function overloads found in Hash++ make use of a container class Container
with aliases DataContainer
, HMAC_DataContainer
, and FilePathsContainer
. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below.
+https://github.com/D7EAD/HashPlusPlus/blob/ff79840060de728177390b2f54716cc4e8d1db30/documentation/hashing/container.cpp#L1-L81
+
+
+While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads.
+https://github.com/D7EAD/HashPlusPlus/blob/2c8e4280291cef5472f41bb2cc00c21e9001fac2/documentation/hashing/container_use.cpp#L14-L37
From b7ef585198e52e05a2e2b9f9c29d052de98e9110 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 19:33:17 -0500
Subject: [PATCH 24/56] Update container.cpp
---
documentation/hashing/container.cpp | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp
index dca99a3..beba1de 100644
--- a/documentation/hashing/container.cpp
+++ b/documentation/hashing/container.cpp
@@ -9,12 +9,31 @@ class Container {
ALGORITHMS algorithm,
const std::vector& data
) noexcept : algorithm(algorithm), data(data) {}
+ Container(
+ ALGORITHMS algorithm,
+ std::vector&& data
+ ) noexcept : algorithm(algorithm), data(std::move(data)) {}
Container(
ALGORITHMS algorithm,
const std::vector& data,
const std::string& key
) noexcept : algorithm(algorithm), data(data), key(key) {}
-
+ Container(
+ ALGORITHMS algorithm,
+ std::vector&& data,
+ const std::string& key
+ ) noexcept : algorithm(algorithm), data(std::move(data)), key(key) {}
+ Container(
+ ALGORITHMS algorithm,
+ const std::vector& data,
+ std::string&& key
+ ) noexcept : algorithm(algorithm), data(data), key(std::move(key)) {}
+ Container(
+ ALGORITHMS algorithm,
+ std::vector&& data,
+ std::string&& key
+ ) noexcept : algorithm(algorithm), data(std::move(data)), key(std::move(key)) {}
+
template ...>, int> = 0>
Container(
From 8a22574b0e71709ddbb0b6d3525f20a807a6e056 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 19:34:38 -0500
Subject: [PATCH 25/56] Update README.md
---
documentation/hashing/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
index 4f480cf..4f2f88a 100644
--- a/documentation/hashing/README.md
+++ b/documentation/hashing/README.md
@@ -31,7 +31,7 @@ template static hashpp::hashCollection getHashes(hashpp::ALG
```
Some function overloads found in Hash++ make use of a container class Container
with aliases DataContainer
, HMAC_DataContainer
, and FilePathsContainer
. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below.
-https://github.com/D7EAD/HashPlusPlus/blob/ff79840060de728177390b2f54716cc4e8d1db30/documentation/hashing/container.cpp#L1-L81
+https://github.com/D7EAD/HashPlusPlus/blob/b7ef585198e52e05a2e2b9f9c29d052de98e9110/documentation/hashing/container.cpp#L1-L100
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads.
From 305aba5958789eb309889c3abba571b186afd5b5 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Tue, 6 Dec 2022 23:17:37 -0500
Subject: [PATCH 26/56] Update container.cpp
---
documentation/hashing/container.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container.cpp
index beba1de..5472d23 100644
--- a/documentation/hashing/container.cpp
+++ b/documentation/hashing/container.cpp
@@ -93,7 +93,7 @@ class Container {
// Holds arbitrary data; how this data is defined is determined
// by the functions that the container containing said data is passed to.
- // (e.g., a call to getFilesHashes with a container will treat all data
+ // (e.g., a call to getFilesHashes with a container will treat all data
// in it as paths to files to be hashed, and a call to getHashes with
// a container will treat all data as generic data to be hashed)
std::vector data;
From 405c33001003a9ece1e30613eba5f48d37835831 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Wed, 7 Dec 2022 15:43:15 -0500
Subject: [PATCH 27/56] Rename documentation/hashing/container.cpp to
documentation/hashing/container/container.cpp
---
documentation/hashing/{ => container}/container.cpp | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename documentation/hashing/{ => container}/container.cpp (100%)
diff --git a/documentation/hashing/container.cpp b/documentation/hashing/container/container.cpp
similarity index 100%
rename from documentation/hashing/container.cpp
rename to documentation/hashing/container/container.cpp
From 8bf4d2971f5fab4ad0df75ea6f71a012841c504e Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Wed, 7 Dec 2022 15:43:30 -0500
Subject: [PATCH 28/56] Rename documentation/hashing/container_use.cpp to
documentation/hashing/container/container_use.cpp
---
documentation/hashing/{ => container}/container_use.cpp | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename documentation/hashing/{ => container}/container_use.cpp (100%)
diff --git a/documentation/hashing/container_use.cpp b/documentation/hashing/container/container_use.cpp
similarity index 100%
rename from documentation/hashing/container_use.cpp
rename to documentation/hashing/container/container_use.cpp
From dbb9f22a25e19f344061eae8941cb5bd3d13da37 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Wed, 7 Dec 2022 15:44:53 -0500
Subject: [PATCH 29/56] Update README.md
---
documentation/hashing/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
index 4f2f88a..0875c3a 100644
--- a/documentation/hashing/README.md
+++ b/documentation/hashing/README.md
@@ -31,8 +31,8 @@ template static hashpp::hashCollection getHashes(hashpp::ALG
```
Some function overloads found in Hash++ make use of a container class Container
with aliases DataContainer
, HMAC_DataContainer
, and FilePathsContainer
. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below.
-https://github.com/D7EAD/HashPlusPlus/blob/b7ef585198e52e05a2e2b9f9c29d052de98e9110/documentation/hashing/container.cpp#L1-L100
+https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container.cpp#L1-L100
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads.
-https://github.com/D7EAD/HashPlusPlus/blob/2c8e4280291cef5472f41bb2cc00c21e9001fac2/documentation/hashing/container_use.cpp#L14-L37
+https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container_use.cpp#L14-L37
From b7fbc10fc627ab21c39a51698882641e1073c78e Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Thu, 8 Dec 2022 12:41:46 -0500
Subject: [PATCH 30/56] Create getHashes_usage.cpp
---
.../hashing/getHashes/getHashes_usage.cpp | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 documentation/hashing/getHashes/getHashes_usage.cpp
diff --git a/documentation/hashing/getHashes/getHashes_usage.cpp b/documentation/hashing/getHashes/getHashes_usage.cpp
new file mode 100644
index 0000000..9616545
--- /dev/null
+++ b/documentation/hashing/getHashes/getHashes_usage.cpp
@@ -0,0 +1,29 @@
+/*
+
+ Basic usage of Hash++ getHashes method.
+ This file shows basic usage of the above described method
+ and its overloads, as well as how data can be extracted
+ from its returned object.
+
+*/
+
+#include "hashpp.h"
+
+using namespace hashpp;
+
+int main() {
+ // a container holding data to be hashed and algorithm to use
+ DataContainer cont1;
+ cont1.setAlgorithm(ALGORITHMS::SHA2_256);
+ cont1.setData("dataToHash1", "dataToHash2", "dataToHash3");
+
+ // acquiring the hashes of the data contained in the above
+ // container using its set algorithm (SHA2-256).
+ hashCollection hashes = get::getHashes(cont1);
+
+ // printing the resulting hashes via hashCollection::operator[]
+ // with specific algorithm name
+ for (auto& hash : hashes["SHA2-256"]) {
+ std::cout << hash << std::endl;
+ }
+}
From 97eac3f461a144361041c6a111a4b84a7496f27e Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Thu, 8 Dec 2022 12:43:22 -0500
Subject: [PATCH 31/56] Update README.md
---
documentation/hashing/README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
index 0875c3a..9541ee8 100644
--- a/documentation/hashing/README.md
+++ b/documentation/hashing/README.md
@@ -36,3 +36,7 @@ https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c5
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads.
https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container_use.cpp#L14-L37
+
+
+As you can see above, when given a properly created Container
, the library function getHashes(...)
can easily calculate and retrieve the hash digests of the passed data contained in the container(s). The function getHashes(...)
itself, though, returns a hashCollection
object. This object can be parsed quite easily:
+https://github.com/D7EAD/HashPlusPlus/blob/b7fbc10fc627ab21c39a51698882641e1073c78e/documentation/hashing/getHashes/getHashes_usage.cpp#L10-L29
From 4186529653b276a51b20074b7145c9574e3ec4e4 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Thu, 8 Dec 2022 13:00:32 -0500
Subject: [PATCH 32/56] Add singular Container overloads for getXs(...)
---
include/hashpp.h | 341 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 338 insertions(+), 3 deletions(-)
diff --git a/include/hashpp.h b/include/hashpp.h
index 706ee2a..5b3c66c 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -3153,7 +3153,88 @@ namespace hashpp {
}
}
- // function to return a collection of resulting hashes from passed data containers
+ // function to return a collection of resulting hashes from passed data container(s)
+ static hashpp::hashCollection getHashes(const DataContainer& dataSet) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+
+ switch (dataSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& data : dataSet.getData()) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& data : dataSet.getData()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(data));
+ }
+ break;
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
static hashpp::hashCollection getHashes(const std::vector& dataSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
@@ -3378,7 +3459,88 @@ namespace hashpp {
}
}
- // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data containers
+ // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data container(s)
+ static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+
+ switch (keyDataSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD5.push_back(hashpp::MD::MD5().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD4.push_back(hashpp::MD::MD4().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vMD2.push_back(hashpp::MD::MD2().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& data : keyDataSet.getData()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHMAC(keyDataSet.getKey(), data));
+ }
+ break;
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
static hashpp::hashCollection getHMACs(const std::vector& keyDataSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
@@ -3647,7 +3809,179 @@ namespace hashpp {
}
}
- // function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support)
+ // function to return a collection of resulting hashes from selected ALGORITHMS and passed file path container(s) (with recursive directory support)
+ static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet) {
+ std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
+
+ switch (filePathSet.getAlgorithm()) {
+ case hashpp::ALGORITHMS::MD5: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vMD5.push_back(hashpp::MD::MD5().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vMD4.push_back(hashpp::MD::MD4().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vMD2.push_back(hashpp::MD::MD2().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA1.push_back(hashpp::SHA::SHA1().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ for (const std::string& path : filePathSet.getData()) {
+ if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path)) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path)));
+ }
+ else if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) {
+ for (const std::filesystem::directory_entry& item : std::filesystem::recursive_directory_iterator(path)) {
+ if (item.is_regular_file()) {
+ vSHA2_512_256.push_back(hashpp::SHA::SHA2_512_256().getHash(item.path()));
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ return hashCollection {
+ {
+ { "MD5", vMD5 },
+ { "MD4", vMD4 },
+ { "MD2", vMD2 },
+ { "SHA1", vSHA1 },
+ { "SHA2-224", vSHA2_224 },
+ { "SHA2-256", vSHA2_256 },
+ { "SHA2-384", vSHA2_384 },
+ { "SHA2-512", vSHA2_512 },
+ { "SHA2-512-224", vSHA2_512_224 },
+ { "SHA2-512-256", vSHA2_512_256 }
+ }
+ };
+ }
+
+ // function to return a collection of resulting hashes from selected ALGORITHMS and passed file path container(s) (with recursive directory support)
static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
@@ -3821,6 +4155,7 @@ namespace hashpp {
};
}
+ // function to return a collection of resulting hashes from selected ALGORITHMS and passed file path container(s) (with recursive directory support)
static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
From 2815c7a0d1a9c18a92136681ca716a63217993d2 Mon Sep 17 00:00:00 2001
From: Dread <42398281+D7EAD@users.noreply.github.com>
Date: Thu, 8 Dec 2022 13:15:06 -0500
Subject: [PATCH 33/56] Update comments.
---
include/hashpp.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/hashpp.h b/include/hashpp.h
index 5b3c66c..ffdff08 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -3235,6 +3235,7 @@ namespace hashpp {
};
}
+ // function to return a collection of resulting hashes from passed data container(s)
static hashpp::hashCollection getHashes(const std::vector& dataSets) {
std::vector vMD5, vMD4, vMD2, vSHA1, vSHA2_224, vSHA2_256, vSHA2_384, vSHA2_512, vSHA2_512_224, vSHA2_512_256;
@@ -3317,7 +3318,8 @@ namespace hashpp {
}
};
}
-
+
+ // function to return a collection of resulting hashes from passed data container(s)
static hashpp::hashCollection getHashes(const std::initializer_list& dataSets) {
std::vector