Entry
Encoding/decoding base X
Jul 5th, 2000 10:03
Nathan Wallace, Hans Nowak, Snippet 351, Python Snippet Support Team
"""
Packages: maths.bases
"""
""" 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 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 "Encoder can only be called with integer or string"
def __repr__(self):
return "Encoder<%d>" % len(self.basestr)
binaryEncoder = Encoder(2)
def itob(x):
""" Integer to binary conversion. """
return binaryEncoder.encode(x)
def btoi(str):
""" Binary to integer conversion. """
return binaryEncoder.decode(str)
if __name__ == "__main__":
data1 = ["13", "89", "nadia", "Nadia18", "nadia18", "1r", "hW"]
def _test2():
e = Encoder(16)
print e.decode("33")
print e.encode(33)
print e
e = Encoder(2)
print e.encode(33)
print e(117)
print e
print "61 is", binaryEncoder.encode(61), "in binary"
_test2()