baseconv.py - convert base 10 integers to base X and back again

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
"""
Convert numbers from base 10 integers to base X strings and back again.

Sample usage:

>>> base20 = BaseConverter('0123456789abcdefghij')
>>> base20.from_decimal(1234)
'31e'
>>> base20.to_decimal('31e')
1234
"""

class BaseConverter(object):
    decimal_digits = "0123456789"
    
    def __init__(self, digits):
        self.digits = digits
    
    def from_decimal(self, i):
        return self.convert(i, self.decimal_digits, self.digits)
    
    def to_decimal(self, s):
        return int(self.convert(s, self.digits, self.decimal_digits))
    
    def convert(number, fromdigits, todigits):
        # Based on http://code.activestate.com/recipes/111286/
        if str(number)[0] == '-':
            number = str(number)[1:]
            neg = 1
        else:
            neg = 0

        # make an integer out of the number
        x = 0
        for digit in str(number):
           x = x * len(fromdigits) + fromdigits.index(digit)
    
        # create the result in base 'len(todigits)'
        if x == 0:
            res = todigits[0]
        else:
            res = ""
            while x > 0:
                digit = x % len(todigits)
                res = todigits[digit] + res
                x = int(x / len(todigits))
            if neg:
                res = '-' + res
        return res
    convert = staticmethod(convert)

bin = BaseConverter('01')
hexconv = BaseConverter('0123456789ABCDEF')
base62 = BaseConverter(
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'
)

if __name__ == '__main__':
    nums = [-10 ** 10, 10 ** 10] + range(-100, 100)
    for convertor in [bin, hexconv, base62]:
        for i in nums:
            assert i == bin.to_decimal(bin.from_decimal(i)), '%s failed' % i

More like this

  1. Query lookups using operators by diverman 3 years, 8 months ago
  2. Friendly ID by willhardy 5 years, 4 months ago
  3. versioned_media templatetag by dnordberg 5 years, 8 months ago
  4. Pattern to integer list function by marinho 6 years, 4 months ago
  5. Integer list to pattern function by marinho 6 years, 4 months ago

Comments

7times9 (on April 21, 2009):

You are testing the <built-in function hex>. Did you mean [bin, hexconv, base62]?

#

simon (on April 28, 2009):

I did - thanks for the correction.

#

7times9 (on May 21, 2009):

Also, all instance of the function bin in the test, should be convertor. And most people spell it converter anyway :-)

#

nileshk (on May 23, 2009):

This line in the sample usage:

>>> base20.from_decimal('31e')

I think should read:

>>> base20.to_decimal('31e')

#

simon (on September 28, 2009):

nileshk - fixed, thanks

#

(Forgotten your password?)