From ffc931dfb8829c8ae36b171d47f3230e10b67cea Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 9 Dec 2017 12:57:02 +0200 Subject: Add support for calculating SHA1 checksums --- libbutl/sha1.mxx | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 libbutl/sha1.mxx (limited to 'libbutl/sha1.mxx') 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 +#include // size_t +#include +#include // strlen() +#endif + +// Other includes. + +#ifdef __cpp_modules +export module butl.sha1; +#ifdef __cpp_lib_modules +import std.core; +#endif +#endif + +#include + +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_; + }; +} -- cgit v1.1