-
Notifications
You must be signed in to change notification settings - Fork 16
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
Test suite #11
Comments
Not enough Coffee! I didn't merge anything for this issue. I was trying to merge changes for #8 sorry for the notifications. I also see uuid6/uuid6-ietf-draft#43 I am open to Test Vectors but I don't have the cycles at the moment to work through them. |
import secrets
import time
def _subsec_decode(value: int, subsec_bits: int, subsec_decimal_digits: int) -> int:
return -(-value * 10 ** subsec_decimal_digits // 2 ** subsec_bits)
def _subsec_encode(value: int, subsec_bits: int, subsec_decimal_digits: int) -> int:
return value * 2 ** subsec_bits // 10 ** subsec_decimal_digits
def uuid7(
unixts: int = None,
subsec: int = None,
seq: int = None,
node: int = None,
subsec_bits: int = 30,
subsec_digits: int = 9,
seq_bits: int = 0,
) -> str:
"""UUIDv7 draft 02"""
node_bits = 86 - subsec_bits - seq_bits
# sanity checks
if subsec_bits < 0 or seq_bits < 0 or node_bits < 0:
raise ValueError("invalid bit value")
if unixts is None or subsec is None:
if unixts is not None or subsec is not None:
raise ValueError("both unixts and subsec need to be set or unset")
if subsec_digits != 9:
raise ValueError("invalid subsec_digits")
unixts, subsec = divmod(time.time_ns(), 10 ** 9)
if unixts < 0:
raise ValueError("unixts needs to be greater than or equal to 0")
if subsec < 0:
raise ValueError("subsec needs to be greater than or equal to 0")
if subsec >= 10 ** subsec_digits:
raise ValueError("subsec overflow")
if seq is not None:
if seq < 0:
raise ValueError("seq needs to be greater than or equal to 0")
if seq >= 2 ** seq_bits:
raise ValueError("seq overflow")
if node is not None:
if node <= 0:
raise ValueError("node needs to be greater than 0")
if node >= 2 ** node_bits:
raise ValueError("node overflow")
subsec_seq_node = _subsec_encode(subsec, subsec_bits, subsec_digits) << (
node_bits + seq_bits
)
if seq:
subsec_seq_node |= seq << node_bits
if node_bits:
while node is None or node == 0:
node = secrets.randbits(node_bits)
subsec_seq_node |= node
subsec_a = subsec_seq_node >> 74
subsec_b = (subsec_seq_node >> 62) & 0x0FFF
uuid_int = (unixts & 0x0FFFFFFFFF) << 92
uuid_int |= subsec_a << 80
uuid_int |= subsec_b << 64
uuid_int |= subsec_seq_node & 0x03FFFFFFFFFFFFFFF
# Set the variant to RFC 4122.
uuid_int |= 0x8000 << 48
# Set the version number.
uuid_int |= 7 << 76
uuid_hex = "%032x" % uuid_int
return "%s-%s-%s-%s-%s" % (
uuid_hex[:8],
uuid_hex[8:12],
uuid_hex[12:16],
uuid_hex[16:20],
uuid_hex[20:],
) I haven't tested this thoroughly, but if there aren't any major bugs, you can pretty easily input whatever you want for
|
I've generated some test vectors with the following snippet. What do you guys think about it? def generate_test_vectors():
for subsec_bits in (10, 12, 20, 24, 30, 40):
for subsec_digits in range(3, 13):
print(f"### {subsec_bits=}, {subsec_digits=}")
for unixts in (0, 1, 2, 2 ** 35, 2 ** 36 - 1):
for subsec in (
0,
1,
2,
10 ** subsec_digits // 2 - 1,
10 ** subsec_digits // 2,
10 ** subsec_digits - 2,
10 ** subsec_digits - 1,
):
for node in (
1,
2,
2 ** (86 - subsec_bits) - 2,
2 ** (86 - subsec_bits) - 1,
):
value = uuid7(
unixts,
subsec,
node=node,
subsec_bits=subsec_bits,
subsec_digits=subsec_digits,
)
print(f"{unixts=}, {subsec=}, {node=} = {value}") Part of the output that covers the common(?) nanosecond case, which requires 30 bits to represent it.
|
@oittaa, I put this on hold because of some changes in Draft 03. If you could take a look at the latest Draft 03 PR that would be great! |
I'm implementing a C# version of UUIDv7 and it looks like I have some problems with my implementation. It would be great to have a common list of tests to check the implementation.
The text was updated successfully, but these errors were encountered: