blob: 909afb0c755592f43925bec039483a9aefa40597 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2018 The Chromium Authors
Ken Rockot8c6991c72018-11-07 21:23:192// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/token.h"
6
7#include <inttypes.h>
8
Jan Keitel601e27632024-07-28 09:56:419#include <array>
Arthur Sonzognie5fff99c2024-02-21 15:58:2410#include <optional>
Helmut Januschka1dce9dc2024-06-11 13:05:3511#include <string_view>
Arthur Sonzognie5fff99c2024-02-21 15:58:2412
Maksim Ivanov6177f0e2022-12-14 00:32:4913#include "base/check.h"
Lei Zhangf3c81cb2023-09-29 18:07:1714#include "base/hash/hash.h"
Collin Bakerffe1d0eb2019-08-05 23:00:4515#include "base/pickle.h"
Ken Rockot8c6991c72018-11-07 21:23:1916#include "base/rand_util.h"
17#include "base/strings/stringprintf.h"
18
19namespace base {
20
21// static
22Token Token::CreateRandom() {
23 Token token;
24
25 // Use base::RandBytes instead of crypto::RandBytes, because crypto calls the
26 // base version directly, and to prevent the dependency from base/ to crypto/.
danakj95305d272024-05-09 20:38:4427 RandBytes(byte_span_from_ref(token));
Maksim Ivanov6177f0e2022-12-14 00:32:4928
29 CHECK(!token.is_zero());
30
Ken Rockot8c6991c72018-11-07 21:23:1931 return token;
32}
33
34std::string Token::ToString() const {
danakj95305d272024-05-09 20:38:4435 return StringPrintf("%016" PRIX64 "%016" PRIX64, words_[0], words_[1]);
Ken Rockot8c6991c72018-11-07 21:23:1936}
37
Nigel Tao9af13b82022-05-19 02:01:1638// static
Helmut Januschka1dce9dc2024-06-11 13:05:3539std::optional<Token> Token::FromString(std::string_view string_representation) {
Nigel Tao9af13b82022-05-19 02:01:1640 if (string_representation.size() != 32) {
Arthur Sonzognie5fff99c2024-02-21 15:58:2441 return std::nullopt;
Nigel Tao9af13b82022-05-19 02:01:1642 }
Jan Keitel601e27632024-07-28 09:56:4143 std::array<uint64_t, 2> words;
Peter Kasting28b51cf2022-06-28 15:02:4344 for (size_t i = 0; i < 2; i++) {
Nigel Tao9af13b82022-05-19 02:01:1645 uint64_t word = 0;
46 // This j loop is similar to HexStringToUInt64 but we are intentionally
47 // strict about case, accepting 'A' but rejecting 'a'.
Peter Kasting28b51cf2022-06-28 15:02:4348 for (size_t j = 0; j < 16; j++) {
Nigel Tao9af13b82022-05-19 02:01:1649 const char c = string_representation[(16 * i) + j];
50 if (('0' <= c) && (c <= '9')) {
Peter Kasting28b51cf2022-06-28 15:02:4351 word = (word << 4) | static_cast<uint64_t>(c - '0');
Nigel Tao9af13b82022-05-19 02:01:1652 } else if (('A' <= c) && (c <= 'F')) {
Peter Kasting28b51cf2022-06-28 15:02:4353 word = (word << 4) | static_cast<uint64_t>(c - 'A' + 10);
Nigel Tao9af13b82022-05-19 02:01:1654 } else {
Arthur Sonzognie5fff99c2024-02-21 15:58:2455 return std::nullopt;
Nigel Tao9af13b82022-05-19 02:01:1656 }
57 }
58 words[i] = word;
59 }
Arthur Sonzognie5fff99c2024-02-21 15:58:2460 return std::optional<Token>(std::in_place, words[0], words[1]);
Nigel Tao9af13b82022-05-19 02:01:1661}
62
Collin Bakerffe1d0eb2019-08-05 23:00:4563void WriteTokenToPickle(Pickle* pickle, const Token& token) {
64 pickle->WriteUInt64(token.high());
65 pickle->WriteUInt64(token.low());
66}
67
Arthur Sonzognie5fff99c2024-02-21 15:58:2468std::optional<Token> ReadTokenFromPickle(PickleIterator* pickle_iterator) {
Collin Bakerffe1d0eb2019-08-05 23:00:4569 uint64_t high;
Peter Kasting134ef9af2024-12-28 02:30:0970 if (!pickle_iterator->ReadUInt64(&high)) {
Arthur Sonzognie5fff99c2024-02-21 15:58:2471 return std::nullopt;
Peter Kasting134ef9af2024-12-28 02:30:0972 }
Collin Bakerffe1d0eb2019-08-05 23:00:4573
74 uint64_t low;
Peter Kasting134ef9af2024-12-28 02:30:0975 if (!pickle_iterator->ReadUInt64(&low)) {
Arthur Sonzognie5fff99c2024-02-21 15:58:2476 return std::nullopt;
Peter Kasting134ef9af2024-12-28 02:30:0977 }
Collin Bakerffe1d0eb2019-08-05 23:00:4578
79 return Token(high, low);
80}
81
Lei Zhangf3c81cb2023-09-29 18:07:1782size_t TokenHash::operator()(const Token& token) const {
83 return HashInts64(token.high(), token.low());
84}
85
Ken Rockot8c6991c72018-11-07 21:23:1986} // namespace base