kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/common/sha256_hasher.h (about) 1 /* 2 * Copyright 2023 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef KYTHE_CXX_COMMON_SHA256_HASHER_H_ 18 #define KYTHE_CXX_COMMON_SHA256_HASHER_H_ 19 20 #include <openssl/sha.h> 21 22 #include <array> 23 #include <cstddef> 24 #include <string> 25 26 #include "absl/strings/string_view.h" 27 #include "absl/types/span.h" 28 29 namespace kythe { 30 31 /// \brief Encapsulates BoringSSL SHA256 hashing in a friendly interface. 32 class Sha256Hasher { 33 /// \brief An internal type for handling a variety of valid "byte" 34 /// representations without the need for client-side reinterpret casts. 35 class ByteView { 36 template <typename... Ts> 37 struct first_convertible { 38 template <typename From, typename T> 39 struct is_convertible : std::is_convertible<From, T> { 40 using type = T; 41 }; 42 template <typename From> 43 using from = typename std::disjunction<is_convertible<From, Ts>...>::type; 44 }; 45 46 public: 47 template <typename T, typename Dest = first_convertible< 48 absl::string_view, absl::Span<const std::byte>, 49 absl::Span<const unsigned char>, 50 absl::Span<const char>>::from<T>> 51 ByteView(T&& data) // NOLINT 52 : ByteView(Dest(data)) {} 53 54 ByteView(absl::string_view data) // NOLINT 55 : ByteView(data.data(), data.size()) {} 56 ByteView(absl::Span<const std::byte> data) // NOLINT 57 : ByteView(data.data(), data.size()) {} 58 ByteView(absl::Span<const unsigned char> data) // NOLINT 59 : ByteView(data.data(), data.size()) {} 60 ByteView(absl::Span<const char> data) // NOLINT 61 : ByteView(data.data(), data.size()) {} 62 63 ByteView(const std::byte* data, std::size_t size) 64 : ByteView(reinterpret_cast<const unsigned char*>(data), size) {} 65 ByteView(const char* data, std::size_t size) 66 : ByteView(reinterpret_cast<const unsigned char*>(data), size) {} 67 ByteView(const unsigned char* data, std::size_t size) : data_(data, size) {} 68 69 auto data() const { return data_.data(); } 70 auto size() const { return data_.size(); } 71 72 private: 73 absl::Span<const unsigned char> data_; 74 }; 75 76 public: 77 /// \brief Initializes a new SHA256 hash. 78 Sha256Hasher(); 79 explicit Sha256Hasher(ByteView initial) : Sha256Hasher() { Update(initial); } 80 81 /// \brief Copyable/moveable. 82 Sha256Hasher(const Sha256Hasher&); 83 Sha256Hasher& operator=(const Sha256Hasher&); 84 Sha256Hasher(Sha256Hasher&&); 85 Sha256Hasher& operator=(Sha256Hasher&&); 86 87 /// \brief Update the hash with the provided data. 88 Sha256Hasher& Update(ByteView data) &; 89 Sha256Hasher&& Update(ByteView data) &&; 90 91 /// \brief Finalize the hash and return it as a binary array. 92 std::array<std::byte, SHA256_DIGEST_LENGTH> Finish() &&; 93 void Finish(std::byte* out) &&; 94 95 /// \brief Convenience function which finalizes the hash and returns the 96 /// result as a binary-containing string. 97 std::string FinishBinString() &&; 98 99 /// \brief Convenience function which finalizes the hash and returns the 100 /// result as a lower-case hex-encoded string. 101 std::string FinishHexString() &&; 102 103 private: 104 ::SHA256_CTX context_; 105 }; 106 107 // inline copy/move to silence triviality warning on Finish. 108 inline Sha256Hasher::Sha256Hasher(const Sha256Hasher&) = default; 109 inline Sha256Hasher& Sha256Hasher::operator=(const Sha256Hasher&) = default; 110 inline Sha256Hasher::Sha256Hasher(Sha256Hasher&&) = default; 111 inline Sha256Hasher& Sha256Hasher::operator=(Sha256Hasher&&) = default; 112 113 } // namespace kythe 114 115 #endif // KYTHE_CXX_COMMON_SHA256_HASHER_H_