>>& algorithmPathPairs)
-```
+You can find detailed documentation in the /documentation directory.
diff --git a/documentation/HMACs/README.md b/documentation/HMACs/README.md
new file mode 100644
index 0000000..2fadd44
--- /dev/null
+++ b/documentation/HMACs/README.md
@@ -0,0 +1,39 @@
+Keyed-Hash Message Authentication Codes (HMACs)
+While they may sound considerably more complicated, HMACs aren't too different from cryptographic hashes at the end of the day. HMACs are keyed hashes of data meaning, simply, that an HMAC is used to generate a unique hash digest of data when that data is paired with another specific piece of data--a key.
+
+Take, for instance, the simple example hash function of H(x) = y
where H
is our hash function, x
is our input data, and y
is our output hash digest. The output digest depends on two things:
+
+- The hash function in use.
+- The input supplied to said function.
+
+Now, take, for instance, the following naive keyed hash algorithm *H(x + k) = y
where H
is our hash function, x
is our input data, k
is our key data, and y
is our output hash digest. The output digest now depends on three things:
+
+- The hash function in use.
+- The input supplied to said function.
+- The key data.
+
+Hash functions provide collision-resistance whereas an HMAC provides both collision-resistance and unforgeability. Due to this provided element of unforgeability, HMACs are used in combination with hash algorithms to prove not only that data is unmodified, but that whoever calculated the hash for said data did so with the correct key--otherwise the incorrect HMAC would result.
+
+Simply put, a hash allows for verification of the authenticity of data whereas an HMAC allows for verification of both the authenticity of data and the originator of said data.
+
+*Keep in mind that HMACs do not simply operate as a hash function H
applied on a key k
appended to data x
. How HMACs are calculated is a bit more nuanced. Hash algorithms are not HMACs and vice-versa--the HMAC mechanism works atop existing hash algorithms. You can read more about the RFC specification here.
+
+
+Using Hash++
+Hash++ offers a simple set of methods to generate one or multiple HMACs given data and an associated key. You can find the signatures for the functions below.
+
+```
+static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data;
+static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet);
+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);
+```
+
+
+You can easily generate an HMAC for a single piece of data using Hash++. See below for an example.
+https://github.com/D7EAD/HashPlusPlus/blob/0ac434933e4d54b584b810d863a9f1a4a4f5f7b4/documentation/HMACs/getHMAC/getHMAC_usage.cpp#L10-L29
+
+
+In order to generate several HMACs for several pieces of data, we can use a Container
alias HMAC_DataContainer
(if you have not read about the Container class used by Hash++, please see the documentation for Hashing). See below for an example.
+https://github.com/D7EAD/HashPlusPlus/blob/fc5edb76cd829794a3fb34c416df7431653044e0/documentation/HMACs/getHMACs/getHMACs_usage.cpp#L14-L42
diff --git a/documentation/HMACs/getHMAC/getHMAC_usage.cpp b/documentation/HMACs/getHMAC/getHMAC_usage.cpp
new file mode 100644
index 0000000..5e9d7e5
--- /dev/null
+++ b/documentation/HMACs/getHMAC/getHMAC_usage.cpp
@@ -0,0 +1,29 @@
+/*
+
+ Basic usage of Hash++ getHMAC 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() {
+ // data we want to get HMAC of
+ std::string dataToHash = "Hello World!";
+
+ // key to use for HMAC
+ std::string key = "secret";
+
+ // get HMAC of dataToHash using SHA-256
+ auto hmac = get::getHMAC(ALGORITHMS::SHA2_256, key, dataToHash);
+
+ // print out the hash
+ std::cout << "HMAC: " << hmac << std::endl;
+
+ // output:
+ // 6fa7b4dea28ee348df10f9bb595ad985ff150a4adfd6131cca677d9acee07dc6
+}
diff --git a/documentation/HMACs/getHMACs/getHMACs_usage.cpp b/documentation/HMACs/getHMACs/getHMACs_usage.cpp
new file mode 100644
index 0000000..e556253
--- /dev/null
+++ b/documentation/HMACs/getHMACs/getHMACs_usage.cpp
@@ -0,0 +1,42 @@
+/*
+
+ Basic usage of Hash++ getHMACs 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() {
+ // create HMAC_DataContainer object
+ // to store algorithm to use, key,
+ // and data to HMAC
+ HMAC_DataContainer hmac_container;
+
+ // set algorithm to use
+ hmac_container.setAlgorithm(ALGORITHMS::SHA2_256);
+
+ // set key to use
+ hmac_container.setKey("secretKey");
+
+ // set data to HMAC
+ hmac_container.setData("dataToHMAC1", "dataToHMAC2", "dataToHMAC3");
+
+ // calculate the HMACs for all data in container
+ // using key and algorithm specified
+ hashCollection hmacs = get::getHMACs(hmac_container);
+
+ // parse and print each HMAC
+ for (auto& hmac : hmacs["SHA2-256"]) {
+ std::cout << hmac << std::endl;
+ }
+
+ // output:
+ // f0dfad2b51176704f8fff07e2c6063417b1d361465b4f9eaacf9b756037bb815
+ // bf912338f4c9d21eff351d085a26b9723eb0da6582039d18a003046c3ae3fbef
+ // abba2bd3400c1b03322fac45539462241ca6ae14a81d58e1db017a9bcb3947b2
+}
diff --git a/documentation/README.md b/documentation/README.md
new file mode 100644
index 0000000..96f2ef9
--- /dev/null
+++ b/documentation/README.md
@@ -0,0 +1,11 @@
+Documentation
+Hash++ is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and keyed-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++.
+
+- 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.
diff --git a/documentation/file_hashing/README.md b/documentation/file_hashing/README.md
new file mode 100644
index 0000000..de52f51
--- /dev/null
+++ b/documentation/file_hashing/README.md
@@ -0,0 +1,17 @@
+Using Hash++ to Generate File Hashes
+Much like how hashes can be generated using generic data, Hash++ provides functions for developers to find hashes for files and files in nested directories. The signatures for the methods can be found below.
+
+```
+static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path);
+static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet);
+static hashpp::hashCollection getFilesHashes(const std::vector& filePathSets);
+static hashpp::hashCollection getFilesHashes(const std::initializer_list& filePathSets);
+```
+
+
+Some file hashing functions, much like some other components of the library, make use of their own Container
alias FilePathsContainer
(if you have not read about the Container
class used by Hash++, please see the documentation for Hashing). You can find an example of a single file being hashed below.
+https://github.com/D7EAD/HashPlusPlus/blob/ba418167da59826cda2a18990a90cf332d75308e/documentation/file_hashing/getFileHash/getFileHash_usage.cpp#L10-L29
+
+
+If you're in the business of hashing multiple files at once, you can find an example of such a use below.
+https://github.com/D7EAD/HashPlusPlus/blob/c007af7d81bdf054a389314ad1d7bbb6d0757262/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp#L14-L35
diff --git a/documentation/file_hashing/getFileHash/getFileHash_usage.cpp b/documentation/file_hashing/getFileHash/getFileHash_usage.cpp
new file mode 100644
index 0000000..664204e
--- /dev/null
+++ b/documentation/file_hashing/getFileHash/getFileHash_usage.cpp
@@ -0,0 +1,29 @@
+/*
+
+ Basic usage of Hash++ getFileHash 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() {
+ // path to file we want to hash (test.txt)
+ std::string pathToFile = "N:/source/test.txt";
+
+ // store the resulting hash object of the file using SHA-256
+ auto hash = get::getFileHash(ALGORITHMS::SHA2_256, pathToFile);
+
+ // print the hash digest
+ std::cout << hash << std::endl;
+
+ // or we can be more specific...
+ std::cout << hash.getString() << std::endl;
+
+ // output:
+ // 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34
+}
diff --git a/documentation/file_hashing/getFileHash/test.txt b/documentation/file_hashing/getFileHash/test.txt
new file mode 100644
index 0000000..0efa7e5
--- /dev/null
+++ b/documentation/file_hashing/getFileHash/test.txt
@@ -0,0 +1 @@
+A hash a day keeps the doctor away.
\ No newline at end of file
diff --git a/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp b/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp
new file mode 100644
index 0000000..b38992a
--- /dev/null
+++ b/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp
@@ -0,0 +1,35 @@
+/*
+
+ Basic usage of Hash++ getFileHashes 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() {
+ // create a FilePathsContainer object
+ FilePathsContainer path_cont1;
+
+ // set its algorithm and some paths
+ path_cont1.setAlgorithm(ALGORITHMS::SHA2_256);
+ path_cont1.setData("N:/source/test.txt", "N:/source/test2.txt", "N:/source/test3.txt");
+
+ // get the hashes of each file via get::getFilesHashes
+ // and store them in a hashCollection object
+ hashCollection hashes = get::getFilesHashes(path_cont1);
+
+ // parse and print the hashes
+ for (auto& hash : hashes["SHA2-256"]) {
+ std::cout << hash << std::endl;
+ }
+
+ // output:
+ // 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34
+ // 7c88d6bc28e9bd6660b96cfa3b69cdbaaaf0187047267106842841357ac03bd8
+ // 44d25e664ce6d6e82beb7a14fe312d7c09c5dc107668a6d40449bc24938e5c73
+}
diff --git a/documentation/file_hashing/getFilesHashes/test.txt b/documentation/file_hashing/getFilesHashes/test.txt
new file mode 100644
index 0000000..0efa7e5
--- /dev/null
+++ b/documentation/file_hashing/getFilesHashes/test.txt
@@ -0,0 +1 @@
+A hash a day keeps the doctor away.
\ No newline at end of file
diff --git a/documentation/file_hashing/getFilesHashes/test2.txt b/documentation/file_hashing/getFilesHashes/test2.txt
new file mode 100644
index 0000000..4f77000
--- /dev/null
+++ b/documentation/file_hashing/getFilesHashes/test2.txt
@@ -0,0 +1 @@
+Too many hashes may lead to gastrointestinal issues.
\ No newline at end of file
diff --git a/documentation/file_hashing/getFilesHashes/test3.txt b/documentation/file_hashing/getFilesHashes/test3.txt
new file mode 100644
index 0000000..afb6ee7
--- /dev/null
+++ b/documentation/file_hashing/getFilesHashes/test3.txt
@@ -0,0 +1 @@
+Passwords should not be stored in plaintext.
\ No newline at end of file
diff --git a/documentation/hashing/README.md b/documentation/hashing/README.md
new file mode 100644
index 0000000..d2b5cb6
--- /dev/null
+++ b/documentation/hashing/README.md
@@ -0,0 +1,47 @@
+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. 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 DataContainer& dataSet)
+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/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/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#L14-L29
+
+
+Parsing hashCollection
objects is great and all when you want to get the hashes of several pieces of data. However, what if you want to get the hash of a single piece of data? To do this, we make use of the library function getHash
which returns a hash
object.
+https://github.com/D7EAD/HashPlusPlus/blob/ffca4d776939f950dbce37d3477bd3e164cc7ba9/documentation/hashing/getHash/getHash_usage.cpp#L14-L26
diff --git a/documentation/hashing/container/container.cpp b/documentation/hashing/container/container.cpp
new file mode 100644
index 0000000..5472d23
--- /dev/null
+++ b/documentation/hashing/container/container.cpp
@@ -0,0 +1,100 @@
+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,
+ 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(
+ 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;
+};
diff --git a/documentation/hashing/container/container_use.cpp b/documentation/hashing/container/container_use.cpp
new file mode 100644
index 0000000..81c2074
--- /dev/null
+++ b/documentation/hashing/container/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 });
+}
diff --git a/documentation/hashing/getHash/getHash_usage.cpp b/documentation/hashing/getHash/getHash_usage.cpp
new file mode 100644
index 0000000..021e03f
--- /dev/null
+++ b/documentation/hashing/getHash/getHash_usage.cpp
@@ -0,0 +1,26 @@
+/*
+
+ Basic usage of Hash++ getHash 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() {
+ // the data we want to hash
+ std::string data = "dataToHash";
+
+ // store the resulting hash object of 'data' using SHA-256
+ auto hash = get::getHash(ALGORITHMS::SHA2_256, data);
+
+ // print the hash digest
+ std::cout << hash << std::endl;
+
+ // or we can be more specific...
+ std::cout << hash.getString() << std::endl;
+}
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;
+ }
+}
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
- */
-}
diff --git a/include/hashpp.h b/include/hashpp.h
index 1c99a67..cfbc9e4 100644
--- a/include/hashpp.h
+++ b/include/hashpp.h
@@ -67,6 +67,7 @@
#include
#include
#include
+#include
#include
namespace hashpp {
@@ -164,18 +165,39 @@ namespace hashpp {
return this->bytesToHexString();
}
+ // get hexadecimal HMAC from key-data pair
+ std::string getHMAC(const std::string& key, const 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 +216,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 +266,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 +299,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 +317,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 +364,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 +396,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 +418,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 +448,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 +564,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 +712,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 +829,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 +910,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 +938,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 +987,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 +1030,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 +1080,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 +1123,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 +1173,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 +1219,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 +1284,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 +1330,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 +1395,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 +1441,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 +1506,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 +1552,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 +1725,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 +1888,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 +2052,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 +2237,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 +2421,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 +2602,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 +2782,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); }
@@ -1953,31 +2857,35 @@ 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) {
- _Ostr << object.hashStr;
+ _Ostr << object.getString();
return _Ostr;
}
hash& operator=(const hashpp::hash& _rhs) noexcept {
- this->hashStr = _rhs.hashStr;
+ 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;
}
- 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:
@@ -1991,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:
@@ -2045,25 +2949,129 @@ 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,
+ 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(
+ 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:
@@ -2106,54 +3114,859 @@ namespace hashpp {
}
}
- // 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;
-
- 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;
- }
- case hashpp::ALGORITHMS::MD4: {
- vMD4.push_back(hashpp::MD::MD4().getHash(_data));
- break;
- }
- case hashpp::ALGORITHMS::MD2: {
- vMD2.push_back(hashpp::MD::MD2().getHash(_data));
- break;
+ // 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 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 }
+ }
+ };
+ }
+
+ // 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;
+
+ 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 passed data container(s)
+ 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>
+ 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 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 }
+ }
+ };
+ }
+
+ // function to return a collection of resulting HMACs from selected ALGORITHMS and passed key-data container(s)
+ 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 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 ALGORITHMS and passed key-data container(s)
+ 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) {
+ 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)) {
+ switch (algorithm) {
+ case hashpp::ALGORITHMS::MD5: {
+ return { hashpp::MD::MD5().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::MD4: {
+ return { hashpp::MD::MD4().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::MD2: {
+ return { hashpp::MD::MD2().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA1: {
+ return { hashpp::SHA::SHA1().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA2_224: {
+ return { hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA2_256: {
+ return { hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA2_384: {
+ return { hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA2_512: {
+ return { hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA2_512_224: {
+ return { hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path)) };
+ }
+ case hashpp::ALGORITHMS::SHA2_512_256: {
+ return { hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path)) };
+ }
+ default: {
+ return hashpp::hash();
+ }
+ }
+ }
+ else {
+ return hashpp::hash();
+ }
+ }
+
+ // 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)));
}
- case hashpp::ALGORITHMS::SHA1: {
- vSHA1.push_back(hashpp::SHA::SHA1().getHash(_data));
- 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_384.push_back(hashpp::SHA::SHA2_384().getHash(item.path()));
+ }
+ }
}
- case hashpp::ALGORITHMS::SHA2_224: {
- vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(_data));
- 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(_data));
- 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(_data));
- 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(_data));
- 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(_data));
- 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(_data));
- 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;
}
}
return hashCollection {
@@ -2169,150 +3982,338 @@ namespace hashpp {
{ "SHA2-512-224", vSHA2_512_224 },
{ "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)) {
- switch (algorithm) {
- case hashpp::ALGORITHMS::MD5: {
- return { hashpp::MD::MD5().getHash(std::filesystem::path(path)) };
+ // 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;
+
+ 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: {
- return { hashpp::MD::MD4().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::MD::MD2().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA1().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA2_224().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA2_256().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA2_384().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA2_512().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(path)) };
+ 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: {
- return { hashpp::SHA::SHA2_512_256().getHash(std::filesystem::path(path)) };
- }
- default: {
- return hashpp::hash();
+ 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;
}
}
}
- else {
- return hashpp::hash();
- }
+ 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 files (with recursive directory support)
- static hashpp::hashCollection getFilesHashes(const std::vector>>& algorithmPathPairs) {
+ // 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;
- 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;
- }
- case hashpp::ALGORITHMS::MD4: {
- vMD4.push_back(hashpp::MD::MD4().getHash(std::filesystem::path(_path)));
- break;
- }
- case hashpp::ALGORITHMS::MD2: {
- vMD2.push_back(hashpp::MD::MD2().getHash(std::filesystem::path(_path)));
- break;
- }
- case hashpp::ALGORITHMS::SHA1: {
- vSHA1.push_back(hashpp::SHA::SHA1().getHash(std::filesystem::path(_path)));
- break;
- }
- case hashpp::ALGORITHMS::SHA2_224: {
- vSHA2_224.push_back(hashpp::SHA::SHA2_224().getHash(std::filesystem::path(_path)));
- break;
- }
- case hashpp::ALGORITHMS::SHA2_256: {
- vSHA2_256.push_back(hashpp::SHA::SHA2_256().getHash(std::filesystem::path(_path)));
- break;
- }
- case hashpp::ALGORITHMS::SHA2_384: {
- vSHA2_384.push_back(hashpp::SHA::SHA2_384().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)));
}
- case hashpp::ALGORITHMS::SHA2_512: {
- vSHA2_512.push_back(hashpp::SHA::SHA2_512().getHash(std::filesystem::path(_path)));
- break;
- }
- case hashpp::ALGORITHMS::SHA2_512_224: {
- vSHA2_512_224.push_back(hashpp::SHA::SHA2_512_224().getHash(std::filesystem::path(_path)));
- break;
- }
- 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()) {
+ vMD5.push_back(hashpp::MD::MD5().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: {
- vMD5.push_back(hashpp::MD::MD5().getHash(item.path()));
- break;
- }
- case hashpp::ALGORITHMS::MD4: {
+ 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;
}
}
}
@@ -2330,7 +4331,7 @@ namespace hashpp {
{ "SHA2-512-256", vSHA2_512_256 }
}
};
- }
+ }
};
#if defined(HASHPP_INCLUDE_METRICS)
@@ -2370,6 +4371,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 +4402,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 +4464,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
}
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;
- }
-}