Created
March 30, 2018 12:05
-
-
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.
This file contains 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
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