Skip to content

Instantly share code, notes, and snippets.

@garthk
Created June 28, 2018 04:38
Show Gist options
  • Save garthk/36ef19fa3d81df96f8adc8520e0d5a57 to your computer and use it in GitHub Desktop.
Save garthk/36ef19fa3d81df96f8adc8520e0d5a57 to your computer and use it in GitHub Desktop.
KSUID generator
"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