Provide functions that produce Globally Unique Identifiers.
More...
Namespaces |
namespace | bdlb |
Detailed Description
- Outline
-
-
- Purpose:
- Provide functions that produce Globally Unique Identifiers.
-
- Classes:
-
- See also:
- Component bdlb_guid
-
- Description:
- This component provides a
struct
, bdlb::GuidUtil
, that serves as a namespace for utility functions that create and work with Globally Unique Identifiers (GUIDs).
- Note that all the GUIDs generated by this component are actually Universally Unique Identifiers (UUIDs), which are a type of GUID. The two terms will be used interchangeably in the documentation below.
-
- Grammar for GUIDs Used in guidFromString:
- This conversion performed by
guidFromString
is intended to be used for GUIDs generated by external sources that have a variety of formats.
-
- GUID String Format:
<SPEC> ::= <BRACED GUID> | <GUID>
<BRACED GUID> ::= '[' <GUID> ']' | '[ ' <GUID> ' ]'
'{' <GUID> '}' | '{ ' <GUID> ' }'
<GUID> ::= <FORMATTED GUID> | <UNFORMATTED GUID>
<FORMATTED GUID> ::= <X>{4} '-' <X>{2} '-' <X>{2} '-' <X>{2} '-' <X>{6}
<UNFORMATTED GUID> ::= <X>{16}
<X> ::= [0123456789ABCDEFabcdef]{2}
EXAMPLES:
---------
{ 87654321-AAAA-BBBB-CCCC-012345654321 }
00010203-0405-0607-0809-101112131415
[00112233445566778899aAbBcCdDeEfF]
-
- Cryptographic Security:
GuidUtil
provides three families of functions for generating GUIDs: generate
, generateNonSecure
, and generateFromName
. The generate
and generateNonSecure
methods use random number generators, with the slower generate
methods aiming to produce cryptographically secure UUIDs by accessing underlying system resources to obtain truly random numbers, and the faster generateNonSecure
methods using a fast high-quality (but not strictly cryptographically secure) in-process random-number generator.
- The
generateFromName
method does not use random numbers, but produces a UUID deterministically based on a given name and namespace. The user should heed the following admonition in RFC 4122: "Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example." In addition, applications that generate name-based UUIDs from untrusted inputs must not assume that such UUIDs will be unique, since collision attacks are already known against the SHA-1 hash algorithm.
-
- Usage:
- Suppose we are building a system for managing records for employees in a large international firm. These records have no natural field which can be used as a unique ID, so a GUID must be created for each employee.
- First let us define a value-type for employees. For the sake of brevity, we provide a limited amount of data in each record. We additionally show a very limited scope of functionality.
bsl::string d_name;
double d_salary;
bdlb::Guid d_guid;
public:
MyEmployee(const string& name, double salary);
const bdlb::Guid& Guid() const;
const bsl::string& name() const;
double salary() const;
};
Next, we create free functions operator<
and operator==
to allow comparison of MyEmployee
objects. We take advantage of the monotonically increasing nature of sequential GUIDs to implement these methods. bool operator== (const MyEmployee& lhs, const MyEmployee& rhs);
bool operator< (const MyEmployee& lhs, const MyEmployee& rhs);
...
MyEmployee::MyEmployee(const string& name, double salary)
: d_name(name)
, d_salary(salary)
{
bdlb::GuidUtil::generate(&d_guid);
}
const bdlb::Guid& MyEmployee::Guid() const
{
return d_guid;
}
const bsl::string& MyEmployee::name() const
{
return d_name;
}
double MyEmployee::salary() const
{
return d_salary;
}
bool operator==(const MyEmployee& lhs, const MyEmployee& rhs)
{
return lhs.Guid() == rhs.Guid();
}
bool operator<(const MyEmployee& lhs, const MyEmployee& rhs)
{
return lhs.Guid() < rhs.Guid();
}
Next, we create some employees: MyEmployee e1("Foo Bar" , 1011970);
MyEmployee e2("John Doe" , 12345);
MyEmployee e3("Joe Six-pack", 1);
Finally, we verify that the generated GUIDs are unique. assert(e1 < e2 || e2 < e1);
assert(e2 < e3 || e3 < e2);
assert(e1 < e3 || e3 < e1);