Browse Source

adding Sha256 helper function

Bernardo Magri 3 months ago
parent
commit
31988edd6f
1 changed files with 45 additions and 0 deletions
  1. 45 0
      src/Sha256.cpp

+ 45 - 0
src/Sha256.cpp

@@ -0,0 +1,45 @@
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <fstream>
+#include <vector>
+#include <stdexcept>
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <array>
+
+std::string sha256_file(const std::string& path) {
+  std::ifstream f(path, std::ios::binary);
+  if (!f) throw std::runtime_error("Cannot open file: " + path);
+
+  EVP_MD_CTX* ctx = EVP_MD_CTX_new();
+  if (!ctx) throw std::runtime_error("EVP_MD_CTX_new failed");
+  const EVP_MD* md = EVP_sha256();
+  if (EVP_DigestInit_ex(ctx, md, nullptr) != 1) {
+    EVP_MD_CTX_free(ctx);
+    throw std::runtime_error("EVP_DigestInit_ex failed");
+  }
+
+  std::vector<char> buf(1 << 20); // 1 MiB chunks
+  while (f) {
+    f.read(buf.data(), buf.size());
+    std::streamsize n = f.gcount();
+    if (n > 0 && EVP_DigestUpdate(ctx, buf.data(), static_cast<size_t>(n)) != 1) {
+      EVP_MD_CTX_free(ctx);
+      throw std::runtime_error("EVP_DigestUpdate failed");
+    }
+  }
+
+  std::array<unsigned char, SHA256_DIGEST_LENGTH> out{};
+  unsigned int outlen = 0;
+  if (EVP_DigestFinal_ex(ctx, out.data(), &outlen) != 1) {
+    EVP_MD_CTX_free(ctx);
+    throw std::runtime_error("EVP_DigestFinal_ex failed");
+  }
+  EVP_MD_CTX_free(ctx);
+
+  std::ostringstream oss;
+  for (size_t i = 0; i < outlen; ++i)
+    oss << std::hex << std::setw(2) << std::setfill('0') << (int)out[i];
+  return oss.str();
+}