mdomke / python-ulid

ULID implementation for Python
https://python-ulid.rtfd.io
MIT License
391 stars 18 forks source link

UUIDs created with ULID don't specify RFC_4122 variant #5

Closed osintalex closed 12 months ago

osintalex commented 1 year ago

I'm creating UUIDs with ULID for use in an application. As part of some data validation libraries in that application, these UUIDs must be RFC_4122 compliant.

However, some of the UUIDs created with ULID fail this check:

import uuid
from ulid import ULID

ulid = ULID.from_str('01GJMN8DEMHMCJKXM3MADM3J45')
uuid_value = ulid.to_uuid()
print(uuid_value.variant == uuid.RFC_4122)  # False
for uuid_created_with_uuid in (uuid.uuid1(), uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org'), uuid.uuid4(),
                               uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')):
    print(uuid_created_with_uuid.variant == uuid.RFC_4122)  # True for all of them

This bit uuid_value.variant == uuid.RFC_4122 is what the data validation library does to check that a UUID is RFC_4122 compliant. It would be great to have that supported with ULID if possible.

mdomke commented 1 year ago

Sadly, I think this is not possible without changing some of the basic constraints of this library. The ULID and the UUID both consist of a 128 bit-sequence, but the layout and interpretation of the underlying structure is very different. When converting a ULID to a UUID we could obviously set the bits of the UUID variant field accordingly, so that it complies with the RFC. This would however make it impossible to do the reverse operation and convert the UUID back to the same ULID.

ulid = ULID()
assert ulid == ULID.from_uuid(ulid.to_uuid())  # This would fail

This being said, I think there is no requirement from the ULID spec side that would hinder us from converting a ULID into a valid, let's say, UUID4.

mdomke commented 12 months ago

Release 2.1.0 includes a method ULID.to_uuid4 which allows you to create an RFC 4122 compliant UUIDv4 from a given ULID.

osintalex commented 12 months ago

Thank you!!