token.cc 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/token.h"
  5. #include <inttypes.h>
  6. #include "base/pickle.h"
  7. #include "base/rand_util.h"
  8. #include "base/strings/stringprintf.h"
  9. #include "third_party/abseil-cpp/absl/types/optional.h"
  10. namespace base {
  11. // static
  12. Token Token::CreateRandom() {
  13. Token token;
  14. // Use base::RandBytes instead of crypto::RandBytes, because crypto calls the
  15. // base version directly, and to prevent the dependency from base/ to crypto/.
  16. base::RandBytes(&token, sizeof(token));
  17. return token;
  18. }
  19. std::string Token::ToString() const {
  20. return base::StringPrintf("%016" PRIX64 "%016" PRIX64, words_[0], words_[1]);
  21. }
  22. // static
  23. absl::optional<Token> Token::FromString(StringPiece string_representation) {
  24. if (string_representation.size() != 32) {
  25. return absl::nullopt;
  26. }
  27. uint64_t words[2];
  28. for (size_t i = 0; i < 2; i++) {
  29. uint64_t word = 0;
  30. // This j loop is similar to HexStringToUInt64 but we are intentionally
  31. // strict about case, accepting 'A' but rejecting 'a'.
  32. for (size_t j = 0; j < 16; j++) {
  33. const char c = string_representation[(16 * i) + j];
  34. if (('0' <= c) && (c <= '9')) {
  35. word = (word << 4) | static_cast<uint64_t>(c - '0');
  36. } else if (('A' <= c) && (c <= 'F')) {
  37. word = (word << 4) | static_cast<uint64_t>(c - 'A' + 10);
  38. } else {
  39. return absl::nullopt;
  40. }
  41. }
  42. words[i] = word;
  43. }
  44. return absl::optional<Token>(absl::in_place, words[0], words[1]);
  45. }
  46. void WriteTokenToPickle(Pickle* pickle, const Token& token) {
  47. pickle->WriteUInt64(token.high());
  48. pickle->WriteUInt64(token.low());
  49. }
  50. absl::optional<Token> ReadTokenFromPickle(PickleIterator* pickle_iterator) {
  51. uint64_t high;
  52. if (!pickle_iterator->ReadUInt64(&high))
  53. return absl::nullopt;
  54. uint64_t low;
  55. if (!pickle_iterator->ReadUInt64(&low))
  56. return absl::nullopt;
  57. return Token(high, low);
  58. }
  59. } // namespace base