Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2018 The Chromium Authors |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef BASE_TOKEN_H_ |
| 6 | #define BASE_TOKEN_H_ |
| 7 | |
| 8 | #include <stdint.h> |
| 9 | |
Jan Keitel | 601e2763 | 2024-07-28 09:56:41 | [diff] [blame] | 10 | #include <array> |
Joe Mason | 0c06b4b | 2023-11-28 00:17:04 | [diff] [blame] | 11 | #include <compare> |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 12 | #include <optional> |
Victor Costan | 57f635e | 2020-07-08 04:08:22 | [diff] [blame] | 13 | #include <string> |
Helmut Januschka | 1dce9dc | 2024-06-11 13:05:35 | [diff] [blame] | 14 | #include <string_view> |
Daniel Cheng | c57cd97 | 2025-04-03 18:18:48 | [diff] [blame] | 15 | #include <utility> |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 16 | |
| 17 | #include "base/base_export.h" |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 18 | #include "base/containers/span.h" |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 19 | |
| 20 | namespace base { |
| 21 | |
| 22 | // A Token is a randomly chosen 128-bit integer. This class supports generation |
| 23 | // from a cryptographically strong random source, or constexpr construction over |
| 24 | // fixed values (e.g. to store a pre-generated constant value). Tokens are |
| 25 | // similar in spirit and purpose to UUIDs, without many of the constraints and |
| 26 | // expectations (such as byte layout and string representation) clasically |
| 27 | // associated with UUIDs. |
| 28 | class BASE_EXPORT Token { |
| 29 | public: |
| 30 | // Constructs a zero Token. |
Victor Costan | 57f635e | 2020-07-08 04:08:22 | [diff] [blame] | 31 | constexpr Token() = default; |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 32 | |
| 33 | // Constructs a Token with |high| and |low| as its contents. |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 34 | constexpr Token(uint64_t high, uint64_t low) : words_{high, low} {} |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 35 | |
Victor Costan | 57f635e | 2020-07-08 04:08:22 | [diff] [blame] | 36 | constexpr Token(const Token&) = default; |
| 37 | constexpr Token& operator=(const Token&) = default; |
| 38 | constexpr Token(Token&&) noexcept = default; |
| 39 | constexpr Token& operator=(Token&&) = default; |
| 40 | |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 41 | // Constructs a new Token with random |high| and |low| values taken from a |
Maksim Ivanov | 6177f0e | 2022-12-14 00:32:49 | [diff] [blame] | 42 | // cryptographically strong random source. The result's |is_zero()| is |
| 43 | // guaranteed to be false. |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 44 | static Token CreateRandom(); |
| 45 | |
| 46 | // The high and low 64 bits of this Token. |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 47 | constexpr uint64_t high() const { return words_[0]; } |
| 48 | constexpr uint64_t low() const { return words_[1]; } |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 49 | |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 50 | constexpr bool is_zero() const { return words_[0] == 0 && words_[1] == 0; } |
| 51 | |
Peter Kasting | ae7e314f | 2024-11-27 18:04:07 | [diff] [blame] | 52 | span<const uint8_t, 16> AsBytes() const { return as_byte_span(words_); } |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 53 | |
Joe Mason | 0c06b4b | 2023-11-28 00:17:04 | [diff] [blame] | 54 | friend constexpr auto operator<=>(const Token& lhs, |
| 55 | const Token& rhs) = default; |
| 56 | friend constexpr bool operator==(const Token& lhs, |
| 57 | const Token& rhs) = default; |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 58 | |
Daniel Cheng | c57cd97 | 2025-04-03 18:18:48 | [diff] [blame] | 59 | template <typename H> |
| 60 | friend H AbslHashValue(H h, const Token& token) { |
| 61 | return H::combine(std::move(h), token.words_); |
| 62 | } |
| 63 | |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 64 | // Generates a string representation of this Token useful for e.g. logging. |
| 65 | std::string ToString() const; |
| 66 | |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 67 | // FromString is the opposite of ToString. It returns std::nullopt if the |
Nigel Tao | 9af13b8 | 2022-05-19 02:01:16 | [diff] [blame] | 68 | // |string_representation| is invalid. |
Helmut Januschka | 1dce9dc | 2024-06-11 13:05:35 | [diff] [blame] | 69 | static std::optional<Token> FromString( |
| 70 | std::string_view string_representation); |
Nigel Tao | 9af13b8 | 2022-05-19 02:01:16 | [diff] [blame] | 71 | |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 72 | private: |
| 73 | // Note: Two uint64_t are used instead of uint8_t[16] in order to have a |
Jan Keitel | 601e2763 | 2024-07-28 09:56:41 | [diff] [blame] | 74 | // simpler implementation, particularly for |ToString()|, |is_zero()|, and |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 75 | // constexpr value construction. |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 76 | |
Jan Keitel | 601e2763 | 2024-07-28 09:56:41 | [diff] [blame] | 77 | std::array<uint64_t, 2> words_ = {0, 0}; |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 78 | }; |
| 79 | |
| 80 | // For use in std::unordered_map. |
Lei Zhang | f3c81cb | 2023-09-29 18:07:17 | [diff] [blame] | 81 | struct BASE_EXPORT TokenHash { |
| 82 | size_t operator()(const Token& token) const; |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 83 | }; |
| 84 | |
Collin Baker | ffe1d0eb | 2019-08-05 23:00:45 | [diff] [blame] | 85 | class Pickle; |
| 86 | class PickleIterator; |
| 87 | |
| 88 | // For serializing and deserializing Token values. |
| 89 | BASE_EXPORT void WriteTokenToPickle(Pickle* pickle, const Token& token); |
Arthur Sonzogni | e5fff99c | 2024-02-21 15:58:24 | [diff] [blame] | 90 | BASE_EXPORT std::optional<Token> ReadTokenFromPickle( |
Collin Baker | ffe1d0eb | 2019-08-05 23:00:45 | [diff] [blame] | 91 | PickleIterator* pickle_iterator); |
| 92 | |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 93 | } // namespace base |
| 94 | |
| 95 | #endif // BASE_TOKEN_H_ |