Skip to content

Instantly share code, notes, and snippets.

@daleobrien
Last active December 19, 2020 09:09
Show Gist options
  • Save daleobrien/1b7c578bfdc1133babe037d757be444c to your computer and use it in GitHub Desktop.
Save daleobrien/1b7c578bfdc1133babe037d757be444c to your computer and use it in GitHub Desktop.
Create a KSUID when using a resolver in DynamoDB
### Create a KSUID
## KSID is 274 Billion times larges than UUID.
## Every second KSID has 64 times the number of ids that UUID has over it's entire key space.
#set($characters="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
##
## Create a new UUID
## Of the form xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx, M&N combine to make 6 bits that don’t change
## So, UUID has only 122bit of random, so combine two to make it fully 128bit
#set($uuid1=$util.autoId())
#set($uuid2=$util.autoId())
#set($uuid=$uuid1.substring(0,8) + $uuid2.substring(24)+ $uuid2.substring(0,6) + $uuid1.substring(30))
##
## Create a timestamp in seconds, offset just like segment.io's implementation
#set($time=$util.time.nowEpochSeconds() - 1400000000)
##
## Convert UUID and Timestamp into one large number
#set($number=$time)
#foreach($index in [0..31])
#set($code=$uuid.charAt($index).hashCode())
#if($code < 96) #set($value=$code - 48) #else #set($value=$code - 87) #end
#set($number=$number*16 + $value)
#end
##
## Base62 encode the large number
#set($ksuid='')
## 2^128 == 62^26.871 and 2^160/(62^26) = 36.52 which is still less than 62
## 26 and 32bit timestamp is good until at least 2150-06-20
## e.g. {id} -> 'aWgEPRomUh6hqvTesTITpFSGZ2e'
#foreach($i in [0..26])
#set($remainder=$number % 62)
#set($number=$number / 62)
#set($ch=$characters.charAt($remainder.hashCode()))
#set($ksuid=$ch + $ksuid)
#end ## never need to pad with '0'
##
## $ksuid now contains a valid uuid
##
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment