|
1 | 1 | r"""UUID objects (universally unique identifiers) according to RFC 4122. |
2 | 2 |
|
3 | 3 | This module provides immutable UUID objects (class UUID) and the functions |
4 | | -uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 |
5 | | -UUIDs as specified in RFC 4122. |
| 4 | +uuid1(), uuid3(), uuid4(), uuid5(), and uuid8() for generating version 1, 3, |
| 5 | +4, 5, and 8 UUIDs as specified in RFC 4122 (superseeded by RFC 9562 but still |
| 6 | +referred to as RFC 4122 for compatibility purposes). |
6 | 7 |
|
7 | 8 | If all you want is a unique ID, you should probably call uuid1() or uuid4(). |
8 | 9 | Note that uuid1() may compromise privacy since it creates a UUID containing |
@@ -129,7 +130,7 @@ class UUID: |
129 | 130 | variant the UUID variant (one of the constants RESERVED_NCS, |
130 | 131 | RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) |
131 | 132 |
|
132 | | - version the UUID version number (1 through 5, meaningful only |
| 133 | + version the UUID version number (1 through 8, meaningful only |
133 | 134 | when the variant is RFC_4122) |
134 | 135 |
|
135 | 136 | is_safe An enum indicating whether the UUID has been generated in |
@@ -214,7 +215,7 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, |
214 | 215 | if not 0 <= int < 1<<128: |
215 | 216 | raise ValueError('int is out of range (need a 128-bit value)') |
216 | 217 | if version is not None: |
217 | | - if not 1 <= version <= 5: |
| 218 | + if not 1 <= version <= 8: |
218 | 219 | raise ValueError('illegal version number') |
219 | 220 | # Set the variant to RFC 4122. |
220 | 221 | int &= ~(0xc000 << 48) |
@@ -719,14 +720,36 @@ def uuid5(namespace, name): |
719 | 720 | hash = sha1(namespace.bytes + name).digest() |
720 | 721 | return UUID(bytes=hash[:16], version=5) |
721 | 722 |
|
| 723 | +def uuid8(a=None, b=None, c=None): |
| 724 | + """Generate a UUID from three custom blocks. |
| 725 | + 'a' is the first 48-bit chunk of the UUID (octets 0-5); |
| 726 | + 'b' is the mid 12-bit chunk (octets 6-7); |
| 727 | + 'c' is the last 62-bit chunk (octets 8-15). |
| 728 | + When a value is not specified, a random value is generated. |
| 729 | + """ |
| 730 | + if a is None: |
| 731 | + import random |
| 732 | + a = random.getrandbits(48) |
| 733 | + if b is None: |
| 734 | + import random |
| 735 | + b = random.getrandbits(12) |
| 736 | + if c is None: |
| 737 | + import random |
| 738 | + c = random.getrandbits(62) |
| 739 | + |
| 740 | + int_uuid_8 = (a & 0xffffffffffff) << 80 |
| 741 | + int_uuid_8 |= (b & 0xfff) << 64 |
| 742 | + int_uuid_8 |= c & 0x3fffffffffffffff |
| 743 | + return UUID(int=int_uuid_8, version=8) |
722 | 744 |
|
723 | 745 | def main(): |
724 | 746 | """Run the uuid command line interface.""" |
725 | 747 | uuid_funcs = { |
726 | 748 | "uuid1": uuid1, |
727 | 749 | "uuid3": uuid3, |
728 | 750 | "uuid4": uuid4, |
729 | | - "uuid5": uuid5 |
| 751 | + "uuid5": uuid5, |
| 752 | + "uuid8": uuid8, |
730 | 753 | } |
731 | 754 | uuid_namespace_funcs = ("uuid3", "uuid5") |
732 | 755 | namespaces = { |
|
0 commit comments