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