aboutsummaryrefslogtreecommitdiff
path: root/libbutl/sha1.mxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-12-09 12:57:02 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-12-09 12:57:02 +0200
commitffc931dfb8829c8ae36b171d47f3230e10b67cea (patch)
treedba7ed1adfcf18bae24c472055c723f5a7208dc9 /libbutl/sha1.mxx
parent5335c09efe07f01c64e8b24d9b6e00125f7438fe (diff)
Add support for calculating SHA1 checksums
Diffstat (limited to 'libbutl/sha1.mxx')
-rw-r--r--libbutl/sha1.mxx107
1 files changed, 107 insertions, 0 deletions
diff --git a/libbutl/sha1.mxx b/libbutl/sha1.mxx
new file mode 100644
index 0000000..5259189
--- /dev/null
+++ b/libbutl/sha1.mxx
@@ -0,0 +1,107 @@
+// file : libbutl/sha1.mxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <cstddef> // size_t
+#include <cstdint>
+#include <cstring> // strlen()
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.sha1;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
+{
+ // SHA1 checksum calculator.
+ //
+ // For a single chunk of data a sum can be obtained in one line, for
+ // example:
+ //
+ // cerr << sha1 ("123").string () << endl;
+ //
+ class LIBBUTL_SYMEXPORT sha1
+ {
+ public:
+ sha1 ();
+
+ // Append binary data.
+ //
+ void
+ append (const void*, std::size_t);
+
+ sha1 (const void* b, std::size_t n): sha1 () {append (b, n);}
+
+ // Append string.
+ //
+ // Note that the hash includes the '\0' terminator. Failed that, a call
+ // with an empty string will be indistinguishable from no call at all.
+ //
+ void
+ append (const std::string& s) {append (s.c_str (), s.size () + 1);}
+
+ void
+ append (const char* s) {append (s, std::strlen (s) + 1);}
+
+ explicit
+ sha1 (const std::string& s): sha1 () {append (s);}
+
+ explicit
+ sha1 (const char* s): sha1 () {append (s);}
+
+ // Extract result.
+ //
+ // It can be obtained as either a 20-byte binary digest or as a 40-
+ // character hex-encoded C-string.
+ //
+ using digest_type = std::uint8_t[20];
+
+ const digest_type&
+ binary () const;
+
+ const char*
+ string () const;
+
+ private:
+ struct context // Note: identical to SHA1_CTX.
+ {
+ union {
+ std::uint8_t b8[20];
+ std::uint32_t b32[5];
+ } h;
+ union {
+ std::uint8_t b8[8];
+ std::uint64_t b64[1];
+ } c;
+ union {
+ std::uint8_t b8[64];
+ std::uint32_t b32[16];
+ } m;
+ std::uint8_t count;
+ };
+
+ union
+ {
+ mutable context ctx_;
+ mutable char buf_[sizeof (context)]; // Also used to store string rep.
+ };
+
+ mutable digest_type bin_;
+ mutable bool done_;
+ };
+}