From 4d30878d8efb86fd110c3693024db5da7aceb776 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 19 Jan 2018 00:02:21 +0300 Subject: Add abbreviated_string() to sha* classes --- libbutl/sha1.mxx | 6 ++++++ libbutl/sha256.cxx | 18 +++++++++++++----- libbutl/sha256.mxx | 14 ++++++++++---- tests/sha1/driver.cxx | 14 +++++++++----- tests/sha256/driver.cxx | 19 ++++++++++++++----- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/libbutl/sha1.mxx b/libbutl/sha1.mxx index 5259189..7ba3c0a 100644 --- a/libbutl/sha1.mxx +++ b/libbutl/sha1.mxx @@ -77,6 +77,12 @@ LIBBUTL_MODEXPORT namespace butl const char* string () const; + std::string + abbreviated_string (std::size_t n) const + { + return std::string (string (), n < 40 ? n : 40); + } + private: struct context // Note: identical to SHA1_CTX. { diff --git a/libbutl/sha256.cxx b/libbutl/sha256.cxx index be29871..694b331 100644 --- a/libbutl/sha256.cxx +++ b/libbutl/sha256.cxx @@ -122,7 +122,7 @@ namespace butl string f; f.reserve (n + 31); - for (size_t i (0); i < n; ++i) + for (size_t i (0); i != n; ++i) { char c (s[i]); if (!isxdigit (c)) @@ -138,7 +138,7 @@ namespace butl } string - fingerprint_to_sha256 (const string& f) + fingerprint_to_sha256 (const string& f, size_t rn) { auto bad = []() {throw invalid_argument ("invalid fingerprint");}; @@ -146,9 +146,16 @@ namespace butl if (n != 32 * 3 - 1) bad (); + if (rn > 64) + rn = 64; + string s; - s.reserve (64); - for (size_t i (0); i < n; ++i) + s.reserve (rn); + + // Note that we continue to validate the fingerprint after the result is + // ready. + // + for (size_t i (0); i != n; ++i) { char c (f[i]); if ((i + 1) % 3 == 0) @@ -161,7 +168,8 @@ namespace butl if (!isxdigit (c)) bad (); - s += lcase (c); + if (s.size () != rn) + s += lcase (c); } } diff --git a/libbutl/sha256.mxx b/libbutl/sha256.mxx index 23a116a..1584be8 100644 --- a/libbutl/sha256.mxx +++ b/libbutl/sha256.mxx @@ -111,6 +111,12 @@ LIBBUTL_MODEXPORT namespace butl const char* string () const; + std::string + abbreviated_string (std::size_t n) const + { + return std::string (string (), n < 64 ? n : 64); + } + private: struct context // Note: identical to SHA256_CTX. { @@ -137,10 +143,10 @@ LIBBUTL_MODEXPORT namespace butl LIBBUTL_SYMEXPORT std::string sha256_to_fingerprint (const std::string&); - // Convert a fingerprint (32 colon-separated hex digit pairs) to the SHA256 - // string representation (64 lower case hex digits). Throw invalid_argument - // if the argument is not a valid fingerprint. + // Convert a fingerprint (32 colon-separated hex digit pairs) to the possibly + // abbreviated SHA256 string representation (up to 64 lower case hex digits). + // Throw invalid_argument if the first argument is not a valid fingerprint. // LIBBUTL_SYMEXPORT std::string - fingerprint_to_sha256 (const std::string&); + fingerprint_to_sha256 (const std::string&, std::size_t = 64); } diff --git a/tests/sha1/driver.cxx b/tests/sha1/driver.cxx index 5f5bb69..a2683d1 100644 --- a/tests/sha1/driver.cxx +++ b/tests/sha1/driver.cxx @@ -33,13 +33,18 @@ main () assert (string (sha1 ("").string ()) != "da39a3ee5e6b4b0d3255bfef95601890afd80709"); - assert (string (sha1 ("123").string ()) == - "cc320164df1a2130045a28f08d3b88bc5bbcc43a"); - assert (string (sha1 ("123", 3).string ()) == "40bd001563085fc35165329ea1ff5c5ecbdbbeef"); { + sha1 h ("123"); + assert (string (h.string ()) == "cc320164df1a2130045a28f08d3b88bc5bbcc43a"); + + assert (h.abbreviated_string (10) == "cc320164df"); + assert (h.abbreviated_string (41) == h.string ()); + } + + { sha1 h; h.append ("1"); h.append (string ("2")); @@ -48,7 +53,6 @@ main () auto& b (h.binary ()); assert (b[0] == 0x58 && b[19] == 0xfd); - string s (h.string ()); - assert (s == "58c596bafad8d007952934af1db9abc5401d4dfd"); + assert (string (h.string ()) == "58c596bafad8d007952934af1db9abc5401d4dfd"); } } diff --git a/tests/sha256/driver.cxx b/tests/sha256/driver.cxx index 191756c..6ba1cd1 100644 --- a/tests/sha256/driver.cxx +++ b/tests/sha256/driver.cxx @@ -33,13 +33,20 @@ main () assert (string (sha256 ("").string ()) != "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); - assert (string (sha256 ("123").string ()) == - "a787b6772e3e4df1b2a04d5eee56f8570ab38825eed1b6a9bda288429b7f29a1"); - assert (string (sha256 ("123", 3).string ()) == "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"); { + sha256 h ("123"); + + assert (string (h.string ()) == + "a787b6772e3e4df1b2a04d5eee56f8570ab38825eed1b6a9bda288429b7f29a1"); + + assert (h.abbreviated_string (10) == "a787b6772e"); + assert (h.abbreviated_string (65) == h.string ()); + } + + { sha256 h; h.append ("1"); h.append (string ("2")); @@ -48,8 +55,7 @@ main () auto& b (h.binary ()); assert (b[0] == 0x20 && b[31] == 0x9d); - string s (h.string ()); - assert (s == + assert (string (h.string ()) == "204d9db65789fbede7829ed77f72ba1f0fe21a833d95abad4849b82f33a69b9d"); } @@ -71,5 +77,8 @@ main () "f49dc002c6b66206a548ae8735329564c2b8c96d9b28856defcafa7f04b54fa6"); assert (fingerprint_to_sha256 (fp) == sh); + assert (fingerprint_to_sha256 (fp, 65) == sh); + assert (fingerprint_to_sha256 (fp, 10) == sh.substr (0, 10)); + assert (sha256_to_fingerprint (sh) == fp); } -- cgit v1.1