Created
June 28, 2018 04:38
-
-
Save garthk/36ef19fa3d81df96f8adc8520e0d5a57 to your computer and use it in GitHub Desktop.
KSUID generator
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
"Functions for generating key-sortable unique IDs (KSUIDs)." | |
import os | |
import time | |
import typing | |
EPOCH = 1400000000 # segment.io epoch (March 5th, 2014) | |
DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' | |
def timestamp_bytes() -> bytes: | |
"Generate four bytes for seconds since ``EPOCH``." | |
seconds = int(time.time() - EPOCH) | |
return int(seconds).to_bytes(4, byteorder='big') | |
def random_bytes(length: int = 16) -> bytes: | |
"Generate ``length`` random bytes." | |
return os.urandom(length) | |
def base62_digits(bignum: int) -> typing.Generator[str, None, None]: | |
"Yield digits." | |
assert isinstance(bignum, int) and bignum > 0, "Can only encode positive integers." | |
while True: | |
yield DIGITS[bignum % 62] | |
bignum = bignum // 62 | |
if bignum <= 0: | |
break | |
else: | |
yield '0' | |
def base62(buf: bytes) -> str: | |
"Encode ``buf` as base62." | |
bignum = int.from_bytes(buf, 'big', signed=False) | |
digits = list(base62_digits(bignum)) | |
digits.reverse() | |
return ''.join(digits) | |
def ksuid(): | |
"Return a segment.io KSUID." | |
return base62(timestamp_bytes() + random_bytes()) | |
if __name__ == '__main__': | |
print(ksuid()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment