Skip to content

Instantly share code, notes, and snippets.

@emesik
Created March 30, 2018 12:05
Show Gist options
  • Save emesik/53288d40bd705208f3fb229ce17b6de0 to your computer and use it in GitHub Desktop.
Save emesik/53288d40bd705208f3fb229ce17b6de0 to your computer and use it in GitHub Desktop.
Encodes and decodes integers as short, easy to type tokens, using custom alphabet.
class Intok(object):
"""Encodes and decodes integers as short, easy to type tokens, using custom
alphabet.
The default alphabet consists of 29 digits and uppercase letters. It has
no vowels to eliminate accidental formation of words, and no glyphs that
could be confused (0 and O, I and 1).
"""
alphabet = 'BCDFGHJKLMNPQRSTVWXZ23456789'
case_sensitive = False
def __init__(self, alphabet=None):
self.alphabet = alphabet or self.alphabet
def encode(self, number):
if number > 0:
sign = ''
elif number == 0:
sign = self.alphabet[0]
else:
sign = '-'
number *= -1
digits = []
while number > 0:
number, remainder = divmod(number, len(self.alphabet))
digits.append(self.alphabet[remainder])
return sign + ''.join(reversed(digits))
def decode(self, token):
if not self.case_sensitive:
token = token.upper()
number = 0
sign = 1
if token[0] == '-':
sign = -1
token = token[1:]
mul = 1
for c in reversed(list(token)):
number += self.alphabet.upper().index(c) * mul
mul *= len(self.alphabet)
return sign * number
if __name__ == '__main__':
ncdr = Intok()
print("alphabet size: %d" % len(ncdr.alphabet))
for i in range(200):
e = ncdr.encode(i)
dn = ncdr.decode(e)
dl = ncdr.decode(e.lower())
du = ncdr.decode(e.upper())
assert i == dn == dl == du
print("%7d: %4s" % (i,e))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment