Skip to content

Instantly share code, notes, and snippets.

@viniciusjarina
Created December 21, 2015 16:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save viniciusjarina/69db5f63a33cadbce7c9 to your computer and use it in GitHub Desktop.
Save viniciusjarina/69db5f63a33cadbce7c9 to your computer and use it in GitHub Desktop.
""" base_x.py
Encoding to, and decoding from, "any" numerical base. Using the Encoder
class, converters for base 16, 8, 2 etc. can easily be defined, but
uncommon bases like 13, 29 or 62 are just as easy. The user can also
provide his own string with "numbers".
24 Dec 98 Creation. [HN]
08 Jan 99 Added BinaryEncoder, btoi, itob.
11 Jan 99 Encoder.__init__: basestr now has default value.
"""
import string
DEFAULT_BASESTR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def _check_uniqueness(str):
""" Check if all characters in string are unique. """
str_new = ""
while str:
c = str[0]
if c in str_new: return 0 # not unique!!
str_new = str_new + c
str = str[1:]
# if we're here, the string has passed the test
return 1
class base_encoder:
""" Encode/decode a string according to a given base. """
def __init__(self, basestr=DEFAULT_BASESTR):
if type(basestr) == type(3):
if basestr > len(DEFAULT_BASESTR):
raise "Encoder: Base too large"
basestr = DEFAULT_BASESTR[:basestr]
assert _check_uniqueness(basestr), "String %s is not unique" % basestr
self.basestr = basestr
def decode(self, str):
""" Decode string str from the given base. """
value = 0L
lenb = len(self.basestr)
for c in str:
try:
index = string.index(self.basestr, c)
except ValueError:
raise ValueError, "Invalid value: %c" % c
value = value * lenb + index
return value
def encode(self, x):
""" Encode number x to the given base. """
str = ""
lenb = len(self.basestr)
while x >= 1:
a, b = divmod(x, lenb)
str = self.basestr[int(b)] + str
x = a
return str
def __call__(self, obj):
if type(obj) == type(""):
return self.decode(obj)
elif type(obj) == type(3):
return self.encode(obj)
else:
raise "Base_Encoder can only be called with integer or string"
def __repr__(self):
return "Base_Encoder<%d>" % len(self.basestr)
binaryEncoder = base_encoder(2)
base36Encoder = base_encoder(36)
base62Encoder = base_encoder(62)
def encode36(x):
""" Integer to base 36 conversion. """
return base36Encoder.encode(x)
def decode36(x):
""" base 36 to Integer conversion. """
return base36Encoder.decode(x)
def encode62(x):
""" Integer to base 62 conversion. """
return base36Encoder.encode(x)
def decode62(x):
""" base 62 to Integer conversion. """
return base36Encoder.decode(x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment