faqts : Computers : Programming : Languages : Python : Snippets

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

8 of 10 people (80%) answered Yes
Recently 7 of 9 people (78%) answered Yes

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()