commit 73549a14de547c2f65c664ce4e76a76b68461ab9
parent 07f49e104b495cf3c4175e4f31d853a69d82c04a
Author: cfillion <cfillion@users.noreply.github.com>
Date: Wed, 5 Dec 2018 18:27:15 -0500
implement SHA256 on macOS
Diffstat:
3 files changed, 113 insertions(+), 0 deletions(-)
diff --git a/src/hash.cpp b/src/hash.cpp
@@ -0,0 +1,53 @@
+#include "hash.hpp"
+
+#include <cstdio>
+
+Hash::Hash(const Algorithm algo)
+ : m_algo(algo)
+{
+ switch(algo) {
+ case SHA256:
+#ifdef __APPLE__
+ CC_SHA256_Init(&m_sha256Context);
+#endif
+ break;
+ }
+}
+
+void Hash::write(const char *data, const size_t len)
+{
+ switch(m_algo) {
+ case SHA256:
+#ifdef __APPLE__
+ CC_SHA256_Update(&m_sha256Context, data, len);
+#endif
+ break;
+ }
+}
+
+const std::string &Hash::digest()
+{
+ if(!m_value.empty())
+ return m_value;
+
+ switch(m_algo) {
+ case SHA256:
+#ifdef __APPLE__
+ unsigned char hash[2 + CC_SHA256_DIGEST_LENGTH] =
+ {SHA256, CC_SHA256_DIGEST_LENGTH};
+ CC_SHA256_Final(&hash[2], &m_sha256Context);
+ setValue(hash, sizeof(hash));
+#endif
+ break;
+ }
+
+ return m_value;
+}
+
+void Hash::setValue(const unsigned char *hash, size_t len)
+{
+ m_value.resize(len * 2);
+
+ for(size_t i = 0; i < len; ++i)
+ sprintf(&m_value[i * 2], "%02x", hash[i]);
+}
diff --git a/src/hash.hpp b/src/hash.hpp
@@ -0,0 +1,31 @@
+#ifndef REAPACK_HASH_HPP
+#define REAPACK_HASH_HPP
+
+#include <string>
+
+#ifdef __APPLE__
+# include <CommonCrypto/CommonDigest.h>
+#endif
+
+class Hash {
+public:
+ enum Algorithm {
+ SHA256 = 0x12,
+ };
+
+ Hash(Algorithm);
+ void write(const char *data, size_t len);
+ const std::string &digest();
+
+private:
+ void setValue(const unsigned char *hash, size_t len);
+
+ Algorithm m_algo;
+ std::string m_value;
+
+#ifdef __APPLE__
+ CC_SHA256_CTX m_sha256Context;
+#endif
+};
+
+#endif
diff --git a/test/hash.cpp b/test/hash.cpp
@@ -0,0 +1,29 @@
+#include "helper.hpp"
+
+#include <hash.hpp>
+
+static const char *M = "[hash]";
+
+TEST_CASE("sha256 hashes", M) {
+ Hash hash(Hash::SHA256);
+
+ SECTION("empty") {
+ REQUIRE(hash.digest() ==
+ "1220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+ }
+
+ SECTION("single chunk") {
+ hash.write("hello world", 11);
+
+ REQUIRE(hash.digest() ==
+ "1220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9");
+ }
+
+ SECTION("split chunks") {
+ hash.write("foo bar", 7);
+ hash.write(" bazqux", 4);
+
+ REQUIRE(hash.digest() ==
+ "1220dbd318c1c462aee872f41109a4dfd3048871a03dedd0fe0e757ced57dad6f2d7");
+ }
+}