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_