• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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_UUID_H_
6 #define BASE_UUID_H_
7 
8 #include <stdint.h>
9 
10 #include <compare>
11 #include <iosfwd>
12 #include <string>
13 #include <string_view>
14 
15 #include "base/base_export.h"
16 #include "base/compiler_specific.h"
17 #include "base/containers/span.h"
18 #include "base/types/pass_key.h"
19 #include "build/build_config.h"
20 
21 namespace content {
22 class FileSystemAccessManagerImpl;
23 }
24 
25 namespace base {
26 
27 class BASE_EXPORT Uuid {
28  public:
29   // Length in bytes of the input required to format the input as a Uuid in the
30   // form of version 4.
31   static constexpr size_t kGuidV4InputLength = 16;
32 
33   // Generate a 128-bit random Uuid in the form of version 4. see RFC 4122,
34   // section 4.4. The format of Uuid version 4 must be
35   // xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, where y is one of [8, 9, a, b]. The
36   // hexadecimal values "a" through "f" are output as lower case characters.
37   // A cryptographically secure random source will be used, but consider using
38   // UnguessableToken for greater type-safety if Uuid format is unnecessary.
39   static Uuid GenerateRandomV4();
40 
41   // Formats a sequence of 16 random bytes as a Uuid in the form of version 4.
42   // `input` must:
43   // - have been randomly generated (e.g. created from an UnguessableToken), and
44   // - be of length 16 (this is checked at compile-time).
45   // Despite taking 128 bits of randomness, certain bits will always be
46   // masked over to adhere to the V4 Uuid format.
47   // Useful in cases where an opaque identifier that is generated from stable
48   // inputs needs to be formatted as a V4 Uuid. Currently only exposed to the
49   // File System Access API to return a V4 Uuid for the getUniqueId() method.
50   static Uuid FormatRandomDataAsV4(
51       base::span<const uint8_t, kGuidV4InputLength> input,
52       base::PassKey<content::FileSystemAccessManagerImpl> pass_key);
53   static Uuid FormatRandomDataAsV4ForTesting(
54       base::span<const uint8_t, kGuidV4InputLength> input);
55 
56   // Returns a valid Uuid if the input string conforms to the Uuid format, and
57   // an invalid Uuid otherwise. Note that this does NOT check if the hexadecimal
58   // values "a" through "f" are in lower case characters.
59   static Uuid ParseCaseInsensitive(std::string_view input);
60   static Uuid ParseCaseInsensitive(std::u16string_view input);
61 
62   // Similar to ParseCaseInsensitive(), but all hexadecimal values "a" through
63   // "f" must be lower case characters.
64   static Uuid ParseLowercase(std::string_view input);
65   static Uuid ParseLowercase(std::u16string_view input);
66 
67   // Constructs an invalid Uuid.
68   Uuid();
69 
70   Uuid(const Uuid& other);
71   Uuid& operator=(const Uuid& other);
72   Uuid(Uuid&& other);
73   Uuid& operator=(Uuid&& other);
74 
is_valid()75   bool is_valid() const { return !lowercase_.empty(); }
76 
77   // Returns the Uuid in a lowercase string format if it is valid, and an empty
78   // string otherwise. The returned value is guaranteed to be parsed by
79   // ParseLowercase().
80   //
81   // NOTE: While AsLowercaseString() is currently a trivial getter, callers
82   // should not treat it as such. When the internal type of base::Uuid changes,
83   // this will be a non-trivial converter. See the TODO above `lowercase_` for
84   // more context.
85   const std::string& AsLowercaseString() const LIFETIME_BOUND;
86 
87   // Invalid Uuids are equal.
88   friend bool operator==(const Uuid&, const Uuid&) = default;
89   // Uuids are 128bit chunks of data so must be indistinguishable if equivalent.
90   friend std::strong_ordering operator<=>(const Uuid&, const Uuid&) = default;
91 
92  private:
93   static Uuid FormatRandomDataAsV4Impl(
94       base::span<const uint8_t, kGuidV4InputLength> input);
95 
96   // TODO(crbug.com/40108138): Consider using a different internal type.
97   // Most existing representations of Uuids in the codebase use std::string,
98   // so matching the internal type will avoid inefficient string conversions
99   // during the migration to base::Uuid.
100   //
101   // The lowercase form of the Uuid. Empty for invalid Uuids.
102   std::string lowercase_;
103 };
104 
105 // For runtime usage only. Do not store the result of this hash, as it may
106 // change in future Chromium revisions.
107 struct BASE_EXPORT UuidHash {
108   size_t operator()(const Uuid& uuid) const;
109 };
110 
111 // Stream operator so Uuid objects can be used in logging statements.
112 BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Uuid& uuid);
113 
114 }  // namespace base
115 
116 #endif  // BASE_UUID_H_
117