Last active
July 18, 2026 00:39
-
-
Save Decapitated/ea7ecb021c61bb965bc783939cba1797 to your computer and use it in GitHub Desktop.
Implementation of UUID in Godot. Currently supports V4.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ## Based on RFC 9562. | |
| ## https://www.rfc-editor.org/rfc/rfc9562.html | |
| @tool | |
| class_name UUID extends RefCounted | |
| # NCS = Reserved. Network Computing System (NCS) backward compatibility, and includes Nil UUID. | |
| # RFC_9562 = The variant specified in this class. | |
| # MICROSOFT = Reserved. Microsoft Corporation backward compatibility. | |
| # RESERVED = Reserved for future definition and includes Max UUID. | |
| enum UUIDVariant { NCS, RFC_9562, MICROSOFT, RESERVED, INVALID } | |
| static func v4() -> String: | |
| return bytes_to_string(v4_array()) | |
| #region V4 Field and Bit Layout | |
| # |0 1 2 3 | | |
| # |0 1 2 3 4 5 6 7|8 9 0 1 2 3 4 5|6 7 8 9 0 1 2 3|4 5 6 7 8 9 0 1| | |
| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| # | random_a | | |
| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| # | random_a | ver | random_b | | |
| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| # |var| random_c | | |
| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| # | random_c | | |
| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| #endregion | |
| static func v4_array() -> PackedByteArray: | |
| var crypto := Crypto.new() | |
| var bytes := crypto.generate_random_bytes(16) | |
| # Set the 4 most significant bits of the 7th byte to 0100 (Version 4) | |
| bytes[6] = (bytes[6] & 0b0000_1111) | 0b0100_0000 | |
| # Set the 2 most significant bits of the 9th byte to 10 (Variant 1) | |
| bytes[8] = (bytes[8] & 0b0011_1111) | 0b1000_0000 | |
| return bytes | |
| static func bytes_to_string(bytes: PackedByteArray) -> String: | |
| assert(bytes.size() == 16, "Invalid UUID array.") | |
| var hex := bytes.hex_encode() | |
| return "%s-%s-%s-%s-%s" % [ | |
| hex.substr(0, 8), | |
| hex.substr(8, 4), | |
| hex.substr(12, 4), | |
| hex.substr(16, 4), | |
| hex.substr(20, 12)] | |
| static func string_to_bytes(string: String) -> PackedByteArray: | |
| return string.replace("-", "").hex_decode() | |
| #region Version Field List | |
| # MSB0 | MSB1 | MSB2 | MSB3 | Version | Description | |
| # 0 | 0 | 0 | 0 | 0 | Unused. | |
| # 0 | 0 | 0 | 1 | 1 | The Gregorian time-based UUID specified in this document. | |
| # 0 | 0 | 1 | 0 | 2 | Reserved for DCE Security version, with embedded POSIX UUIDs. | |
| # 0 | 0 | 1 | 1 | 3 | The name-based version specified in this document that uses MD5 hashing. | |
| # 0 | 1 | 0 | 0 | 4 | The randomly or pseudorandomly generated version specified in this document. | |
| # 0 | 1 | 0 | 1 | 5 | The name-based version specified in this document that uses SHA-1 hashing. | |
| # 0 | 1 | 1 | 0 | 6 | Reordered Gregorian time-based UUID specified in this document. | |
| # 0 | 1 | 1 | 1 | 7 | Unix Epoch time-based UUID specified in this document. | |
| # 1 | 0 | 0 | 0 | 8 | Reserved for custom UUID formats specified in this document. | |
| # 1 | 0 | 0 | 1 | 9 | Reserved for future definition. | |
| # 1 | 0 | 1 | 0 | 10 | Reserved for future definition. | |
| # 1 | 0 | 1 | 1 | 11 | Reserved for future definition. | |
| # 1 | 1 | 0 | 0 | 12 | Reserved for future definition. | |
| # 1 | 1 | 0 | 1 | 13 | Reserved for future definition. | |
| # 1 | 1 | 1 | 0 | 14 | Reserved for future definition. | |
| # 1 | 1 | 1 | 1 | 15 | Reserved for future definition. | |
| #endregion | |
| static func version(uuid: Variant) -> int: | |
| var bytes: PackedByteArray | |
| if uuid is PackedByteArray: | |
| bytes = uuid | |
| elif uuid is String: | |
| var uuid_string: String = uuid | |
| uuid_string = uuid_string.replace("-", "") | |
| bytes = uuid_string.hex_decode() | |
| if !bytes.is_empty(): | |
| assert(bytes.size() == 16, "Invalid UUID.") | |
| return bytes[6] >> 4 | |
| return 0 | |
| #region Variant Field List | |
| # MSB0 | MSB1 | MSB2 | MSB3 | Variant | Description | |
| # 0 | x | x | x | 1-7 | Reserved. Network Computing System (NCS) backward compatibility, and includes Nil UUID as per Section 5.9. | |
| # 1 | 0 | x | x | 8-9,A-B | The variant specified in this document. | |
| # 1 | 1 | 0 | x | C-D | Reserved. Microsoft Corporation backward compatibility. | |
| # 1 | 1 | 1 | x | E-F | Reserved for future definition and includes Max UUID as per Section 5.10. | |
| #endregion | |
| static func variant(uuid: Variant) -> UUIDVariant: | |
| var bytes: PackedByteArray | |
| if uuid is PackedByteArray: | |
| bytes = uuid | |
| elif uuid is String: | |
| var uuid_string: String = uuid | |
| uuid_string = uuid_string.replace("-", "") | |
| bytes = uuid_string.hex_decode() | |
| if !bytes.is_empty(): | |
| assert(bytes.size() == 16, "Invalid UUID array.") | |
| var variant_byte: int = bytes[8] >> 4 | |
| variant_byte = variant_byte >> 1 # Remove if final bit is used in the future. | |
| if variant_byte == 0b111: | |
| return UUIDVariant.RESERVED | |
| elif variant_byte == 0b110: | |
| return UUIDVariant.MICROSOFT | |
| variant_byte = variant_byte >> 1 | |
| if variant_byte == 0b10: | |
| return UUIDVariant.RFC_9562 | |
| variant_byte = variant_byte >> 1 | |
| if variant_byte == 0b0: | |
| return UUIDVariant.NCS | |
| return UUIDVariant.INVALID |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment