-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
gh-89083: add support for UUID version 8 (RFC 9562) #123224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c3d4745
392d289
26889ea
44b66e6
7be6dc4
8ba3d8b
a14ae9b
7a169c9
b082c90
94c70e9
275deb7
5e97cc3
051f34e
bdf9a77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
:mod:`!uuid` --- UUID objects according to :rfc:`4122` | ||
:mod:`!uuid` --- UUID objects according to :rfc:`9562` | ||
====================================================== | ||
|
||
.. module:: uuid | ||
:synopsis: UUID objects (universally unique identifiers) according to RFC 4122 | ||
:synopsis: UUID objects (universally unique identifiers) according to RFC 9562 | ||
.. moduleauthor:: Ka-Ping Yee <[email protected]> | ||
.. sectionauthor:: George Yoshida <[email protected]> | ||
|
||
|
@@ -12,7 +12,8 @@ | |
|
||
This module provides immutable :class:`UUID` objects (the :class:`UUID` class) | ||
and the functions :func:`uuid1`, :func:`uuid3`, :func:`uuid4`, :func:`uuid5` for | ||
generating version 1, 3, 4, and 5 UUIDs as specified in :rfc:`4122`. | ||
generating version 1, 3, 4, 5, and 8 UUIDs as specified in :rfc:`9562` (which | ||
supersedes :rfc:`4122`). | ||
|
||
If all you want is a unique ID, you should probably call :func:`uuid1` or | ||
:func:`uuid4`. Note that :func:`uuid1` may compromise privacy since it creates | ||
|
@@ -65,7 +66,7 @@ which relays any information about the UUID's safety, using this enumeration: | |
|
||
Exactly one of *hex*, *bytes*, *bytes_le*, *fields*, or *int* must be given. | ||
The *version* argument is optional; if given, the resulting UUID will have its | ||
variant and version number set according to :rfc:`4122`, overriding bits in the | ||
variant and version number set according to :rfc:`9562`, overriding bits in the | ||
given *hex*, *bytes*, *bytes_le*, *fields*, or *int*. | ||
|
||
Comparison of UUID objects are made by way of comparing their | ||
|
@@ -137,7 +138,7 @@ which relays any information about the UUID's safety, using this enumeration: | |
|
||
.. attribute:: UUID.urn | ||
|
||
The UUID as a URN as specified in :rfc:`4122`. | ||
The UUID as a URN as specified in :rfc:`9562`. | ||
|
||
|
||
.. attribute:: UUID.variant | ||
|
@@ -149,9 +150,13 @@ which relays any information about the UUID's safety, using this enumeration: | |
|
||
.. attribute:: UUID.version | ||
|
||
The UUID version number (1 through 5, meaningful only when the variant is | ||
The UUID version number (1 through 8, meaningful only when the variant is | ||
:const:`RFC_4122`). | ||
|
||
.. versionchanged:: next | ||
Added UUID version 8. | ||
|
||
|
||
.. attribute:: UUID.is_safe | ||
|
||
An enumeration of :class:`SafeUUID` which indicates whether the platform | ||
|
@@ -216,6 +221,23 @@ The :mod:`uuid` module defines the following functions: | |
|
||
.. index:: single: uuid5 | ||
|
||
|
||
.. function:: uuid8(a=None, b=None, c=None) | ||
|
||
Generate a pseudo-random UUID according to | ||
:rfc:`RFC 9562, §5.8 <9562#section-5.8>`. | ||
|
||
When specified, the parameters *a*, *b* and *c* are expected to be | ||
positive integers of 48, 12 and 62 bits respectively. If they exceed | ||
their expected bit count, only their least significant bits are kept; | ||
non-specified arguments are substituted for a pseudo-random integer of | ||
appropriate size. | ||
|
||
.. versionadded:: next | ||
|
||
.. index:: single: uuid8 | ||
|
||
|
||
The :mod:`uuid` module defines the following namespace identifiers for use with | ||
:func:`uuid3` or :func:`uuid5`. | ||
|
||
|
@@ -252,7 +274,9 @@ of the :attr:`~UUID.variant` attribute: | |
|
||
.. data:: RFC_4122 | ||
|
||
Specifies the UUID layout given in :rfc:`4122`. | ||
Specifies the UUID layout given in :rfc:`4122`. This constant is kept | ||
for backward compatibility even though :rfc:`4122` has been superseded | ||
by :rfc:`9562`. | ||
|
||
|
||
.. data:: RESERVED_MICROSOFT | ||
|
@@ -267,7 +291,7 @@ of the :attr:`~UUID.variant` attribute: | |
|
||
.. seealso:: | ||
|
||
:rfc:`4122` - A Universally Unique IDentifier (UUID) URN Namespace | ||
:rfc:`9562` - A Universally Unique IDentifier (UUID) URN Namespace | ||
This specification defines a Uniform Resource Name namespace for UUIDs, the | ||
internal format of UUIDs, and methods of generating UUIDs. | ||
|
||
|
@@ -283,7 +307,7 @@ The :mod:`uuid` module can be executed as a script from the command line. | |
|
||
.. code-block:: sh | ||
|
||
python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5}] [-n NAMESPACE] [-N NAME] | ||
python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5,uuid8}] [-n NAMESPACE] [-N NAME] | ||
|
||
The following options are accepted: | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
r"""UUID objects (universally unique identifiers) according to RFC 4122. | ||
r"""UUID objects (universally unique identifiers) according to RFC 4122/9562. | ||
|
||
This module provides immutable UUID objects (class UUID) and the functions | ||
uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 | ||
UUIDs as specified in RFC 4122. | ||
uuid1(), uuid3(), uuid4(), uuid5(), and uuid8() for generating version 1, 3, | ||
4, 5, and 8 UUIDs as specified in RFC 4122/9562. | ||
|
||
If all you want is a unique ID, you should probably call uuid1() or uuid4(). | ||
Note that uuid1() may compromise privacy since it creates a UUID containing | ||
|
@@ -124,12 +124,12 @@ class UUID: | |
|
||
int the UUID as a 128-bit integer | ||
|
||
urn the UUID as a URN as specified in RFC 4122 | ||
urn the UUID as a URN as specified in RFC 4122/9562 | ||
|
||
variant the UUID variant (one of the constants RESERVED_NCS, | ||
RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) | ||
|
||
version the UUID version number (1 through 5, meaningful only | ||
version the UUID version number (1 through 8, meaningful only | ||
when the variant is RFC_4122) | ||
|
||
is_safe An enum indicating whether the UUID has been generated in | ||
|
@@ -214,9 +214,9 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, | |
if not 0 <= int < 1<<128: | ||
raise ValueError('int is out of range (need a 128-bit value)') | ||
if version is not None: | ||
if not 1 <= version <= 5: | ||
if not 1 <= version <= 8: | ||
raise ValueError('illegal version number') | ||
# Set the variant to RFC 4122. | ||
# Set the variant to RFC 4122/9562. | ||
int &= ~(0xc000 << 48) | ||
int |= 0x8000 << 48 | ||
# Set the version number. | ||
|
@@ -355,7 +355,7 @@ def variant(self): | |
|
||
@property | ||
def version(self): | ||
# The version bits are only meaningful for RFC 4122 UUIDs. | ||
# The version bits are only meaningful for RFC 4122/9562 UUIDs. | ||
if self.variant == RFC_4122: | ||
return int((self.int >> 76) & 0xf) | ||
|
||
|
@@ -719,14 +719,37 @@ def uuid5(namespace, name): | |
hash = sha1(namespace.bytes + name).digest() | ||
return UUID(bytes=hash[:16], version=5) | ||
|
||
def uuid8(a=None, b=None, c=None): | ||
"""Generate a UUID from three custom blocks. | ||
|
||
* 'a' is the first 48-bit chunk of the UUID (octets 0-5); | ||
* 'b' is the mid 12-bit chunk (octets 6-7); | ||
* 'c' is the last 62-bit chunk (octets 8-15). | ||
|
||
When a value is not specified, a pseudo-random value is generated. | ||
""" | ||
if a is None: | ||
import random | ||
picnixz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
a = random.getrandbits(48) | ||
if b is None: | ||
import random | ||
b = random.getrandbits(12) | ||
if c is None: | ||
import random | ||
c = random.getrandbits(62) | ||
int_uuid_8 = (a & 0xffff_ffff_ffff) << 80 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense / is it possible to reject values outside the expected value range? For example, reject negative numbers? Maybe something like:
I don't know. Would it be consistent with other uuid functions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UUIDv1 does not reject them so I wouldn't worry too much about it. v3 and v5 are not based on integral inputs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with having the same behavior than uuid1() in this case, since it's documented. |
||
int_uuid_8 |= (b & 0xfff) << 64 | ||
int_uuid_8 |= c & 0x3fff_ffff_ffff_ffff | ||
return UUID(int=int_uuid_8, version=8) | ||
|
||
def main(): | ||
"""Run the uuid command line interface.""" | ||
uuid_funcs = { | ||
"uuid1": uuid1, | ||
"uuid3": uuid3, | ||
"uuid4": uuid4, | ||
"uuid5": uuid5 | ||
"uuid5": uuid5, | ||
"uuid8": uuid8, | ||
} | ||
uuid_namespace_funcs = ("uuid3", "uuid5") | ||
namespaces = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Add :func:`uuid.uuid8` for generating UUIDv8 objects as specified in | ||
:rfc:`9562`. Patch by Bénédikt Tran |
Uh oh!
There was an error while loading. Please reload this page.