Timeflake is a 128-bit, roughly-ordered, URL-safe UUID.
See the codeTimeflake is a 128-bit, roughly-ordered, URL-safe UUID. Inspired by Twitter's Snowflake, Instagram's ID and Firebase's PushID.
* Please consider how the Birthday Paradox might affect your use case. Also read the security note on this readme.
This could be useful to you, if you're looking for a UUID with the following properties:
Some existing alternatives which I considered:
import timeflake
# Create a random Timeflake
flake = timeflake.random()
>>> Timeflake(base62='00mx79Rjxvfgr8qat2CeQDs')
# Get the base62, int, hex or bytes representation
flake.base62
>>> '00mx79Rjxvfgr8qat2CeQDs'
flake.hex
>>> '016fa936bff0997a0a3c428548fee8c9'
flake.int
>>> 1909005012028578488143182045514754249
flake.bytes
>>> b'\x01o\xa96\xbf\xf0\x99z\n<B\x85H\xfe\xe8\xc9'
# Convert to the standard library's UUID type
flake.uuid
>>> UUID('016fa936-bff0-997a-0a3c-428548fee8c9')
# Get the timestamp component
flake.timestamp
>>> 1579091935216
# Get the random component
flake.random
>>> 724773312193627487660233
# Parse an existing flake (you can also pass bytes, hex or int representations)
timeflake.parse(from_base62='0002HCZffkHWhKPVdXxs0YH')
>>> Timeflake('0004fbc6872f70fc9e27355a499e8b6d')
# Create from a user defined timestamp or random value:
timeflake.from_values(1579091935216, 724773312193627487660233)
>>> Timeflake('016fa936bff0997a0a3c428548fee8c9')
128 bits are used to encode:
For example, the timeflake 016fb4209023b444fd07590f81b7b0eb (hex) encodes the following:
016fb4209023 + b444fd07590f81b7b0eb
| |
| |
timestamp random
[48 bits] [80 bits]
In Python:
flake = timeflake.parse(from_hex='016fb4209023b444fd07590f81b7b0eb')
flake.timestamp = 1579275030563 # 2020-01-17T15:30:30.563 UTC
flake.random = 851298578153087956398315
A custom base62 alphabet representation is included, modified to preserve lexicographical order when sorting strings using this encoding. The hex representation has a max length of 32 characters, while the base62 will be 22 characters. Padding is required to be able to derive the encoding from the string length.
The following are all valid representations of the same Timeflake:
int = 1909226360721144613344160656901255403
hex = 016fb4209023b444fd07590f81b7b0eb
base62 = 02i2XhN7hAuaFh3MwztcMd
You can convert a timeflake to any alphabet using the itoa (integer to ASCII) function:
from timeflake.utils import itoa
flake = timeflake.random()
itoa(flake.int, alphabet=timeflake.flake.HEX, padding=32)
You can use timeflakes as primary keys for your models. These fields currently support MySQL, Postgres and Sqlite3.
Example usage:
from timeflake.extensions.django import TimeflakePrimaryKeyBinary
class Item(models.Model):
item_id = TimeflakePrimaryKeyBinary()
# ...
See this gist for an example.
Since the timestamp part is predictable, the search space within any given millisecond is 2^80 random numbers, which is meant to avoid collisions, not to secure or hide information. You should not be using timeflakes for password-reset tokens, API keys or for anything which is security sensitive. There are better libraries which are meant for this use case (for example, the standard library's secrets module).
Please be aware of the privacy implications that time based IDs can have. As Timeflake encodes the precise time in which the ID was created, this could potentially reveal:
Right now the codebase is only tested with Python 3.7+.
No dependencies other than the standard library.
Want to hack on the project? Any kind of contribution is welcome! Simply follow the next steps:
Thank you for making this project better!
Please see the CHANGELOG for more details.
This project is licensed under the MIT license. Please read the LICENSE file for more details.
Overall
Maintained
Code review
PyPI
Latest release
Releases this year
8,226 followers · starred Jan 2021
1,854 followers · starred Jan 2021
228 followers · starred Jan 2021
5,135 followers · starred Apr 2021
Timeflake is a 128-bit, roughly-ordered, URL-safe UUID.
See the codeTimeflake is a 128-bit, roughly-ordered, URL-safe UUID. Inspired by Twitter's Snowflake, Instagram's ID and Firebase's PushID.
* Please consider how the Birthday Paradox might affect your use case. Also read the security note on this readme.
This could be useful to you, if you're looking for a UUID with the following properties:
Some existing alternatives which I considered:
import timeflake
# Create a random Timeflake
flake = timeflake.random()
>>> Timeflake(base62='00mx79Rjxvfgr8qat2CeQDs')
# Get the base62, int, hex or bytes representation
flake.base62
>>> '00mx79Rjxvfgr8qat2CeQDs'
flake.hex
>>> '016fa936bff0997a0a3c428548fee8c9'
flake.int
>>> 1909005012028578488143182045514754249
flake.bytes
>>> b'\x01o\xa96\xbf\xf0\x99z\n<B\x85H\xfe\xe8\xc9'
# Convert to the standard library's UUID type
flake.uuid
>>> UUID('016fa936-bff0-997a-0a3c-428548fee8c9')
# Get the timestamp component
flake.timestamp
>>> 1579091935216
# Get the random component
flake.random
>>> 724773312193627487660233
# Parse an existing flake (you can also pass bytes, hex or int representations)
timeflake.parse(from_base62='0002HCZffkHWhKPVdXxs0YH')
>>> Timeflake('0004fbc6872f70fc9e27355a499e8b6d')
# Create from a user defined timestamp or random value:
timeflake.from_values(1579091935216, 724773312193627487660233)
>>> Timeflake('016fa936bff0997a0a3c428548fee8c9')
128 bits are used to encode:
For example, the timeflake 016fb4209023b444fd07590f81b7b0eb (hex) encodes the following:
016fb4209023 + b444fd07590f81b7b0eb
| |
| |
timestamp random
[48 bits] [80 bits]
In Python:
flake = timeflake.parse(from_hex='016fb4209023b444fd07590f81b7b0eb')
flake.timestamp = 1579275030563 # 2020-01-17T15:30:30.563 UTC
flake.random = 851298578153087956398315
A custom base62 alphabet representation is included, modified to preserve lexicographical order when sorting strings using this encoding. The hex representation has a max length of 32 characters, while the base62 will be 22 characters. Padding is required to be able to derive the encoding from the string length.
The following are all valid representations of the same Timeflake:
int = 1909226360721144613344160656901255403
hex = 016fb4209023b444fd07590f81b7b0eb
base62 = 02i2XhN7hAuaFh3MwztcMd
You can convert a timeflake to any alphabet using the itoa (integer to ASCII) function:
from timeflake.utils import itoa
flake = timeflake.random()
itoa(flake.int, alphabet=timeflake.flake.HEX, padding=32)
You can use timeflakes as primary keys for your models. These fields currently support MySQL, Postgres and Sqlite3.
Example usage:
from timeflake.extensions.django import TimeflakePrimaryKeyBinary
class Item(models.Model):
item_id = TimeflakePrimaryKeyBinary()
# ...
See this gist for an example.
Since the timestamp part is predictable, the search space within any given millisecond is 2^80 random numbers, which is meant to avoid collisions, not to secure or hide information. You should not be using timeflakes for password-reset tokens, API keys or for anything which is security sensitive. There are better libraries which are meant for this use case (for example, the standard library's secrets module).
Please be aware of the privacy implications that time based IDs can have. As Timeflake encodes the precise time in which the ID was created, this could potentially reveal:
Right now the codebase is only tested with Python 3.7+.
No dependencies other than the standard library.
Want to hack on the project? Any kind of contribution is welcome! Simply follow the next steps:
Thank you for making this project better!
Please see the CHANGELOG for more details.
This project is licensed under the MIT license. Please read the LICENSE file for more details.
Overall
Maintained
Code review
PyPI
Latest release
Releases this year
8,226 followers · starred Jan 2021
1,854 followers · starred Jan 2021
228 followers · starred Jan 2021
5,135 followers · starred Apr 2021