Project

General

Profile

Statistics
| Branch: | Revision:

root / env / lib / python2.7 / site-packages / django / utils / baseconv.py @ 1a305335

History | View | Annotate | Download (2.91 KB)

1
# Copyright (c) 2010 Taurinus Collective. All rights reserved.
2
# Copyright (c) 2009 Simon Willison. All rights reserved.
3
# Copyright (c) 2002 Drew Perttula. All rights reserved.
4
#
5
# License:
6
#   Python Software Foundation License version 2
7
#
8
# See the file "LICENSE" for terms & conditions for usage, and a DISCLAIMER OF
9
# ALL WARRANTIES.
10
#
11
# This Baseconv distribution contains no GNU General Public Licensed (GPLed)
12
# code so it may be used in proprietary projects just like prior ``baseconv``
13
# distributions.
14
#
15
# All trademarks referenced herein are property of their respective holders.
16
#
17

    
18
"""
19
Convert numbers from base 10 integers to base X strings and back again.
20

21
Sample usage::
22

23
  >>> base20 = BaseConverter('0123456789abcdefghij')
24
  >>> base20.encode(1234)
25
  '31e'
26
  >>> base20.decode('31e')
27
  1234
28
  >>> base20.encode(-1234)
29
  '-31e'
30
  >>> base20.decode('-31e')
31
  -1234
32
  >>> base11 = BaseConverter('0123456789-', sign='$')
33
  >>> base11.encode('$1234')
34
  '$-22'
35
  >>> base11.decode('$-22')
36
  '$1234'
37

38
"""
39

    
40
BASE2_ALPHABET = '01'
41
BASE16_ALPHABET = '0123456789ABCDEF'
42
BASE56_ALPHABET = '23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz'
43
BASE36_ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz'
44
BASE62_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
45
BASE64_ALPHABET = BASE62_ALPHABET + '-_'
46

    
47
class BaseConverter(object):
48
    decimal_digits = '0123456789'
49

    
50
    def __init__(self, digits, sign='-'):
51
        self.sign = sign
52
        self.digits = digits
53
        if sign in self.digits:
54
            raise ValueError('Sign character found in converter base digits.')
55

    
56
    def __repr__(self):
57
        return "<BaseConverter: base%s (%s)>" % (len(self.digits), self.digits)
58

    
59
    def encode(self, i):
60
        neg, value = self.convert(i, self.decimal_digits, self.digits, '-')
61
        if neg:
62
            return self.sign + value
63
        return value
64

    
65
    def decode(self, s):
66
        neg, value = self.convert(s, self.digits, self.decimal_digits, self.sign)
67
        if neg:
68
            value = '-' + value
69
        return int(value)
70

    
71
    def convert(self, number, from_digits, to_digits, sign):
72
        if str(number)[0] == sign:
73
            number = str(number)[1:]
74
            neg = 1
75
        else:
76
            neg = 0
77

    
78
        # make an integer out of the number
79
        x = 0
80
        for digit in str(number):
81
            x = x * len(from_digits) + from_digits.index(digit)
82

    
83
        # create the result in base 'len(to_digits)'
84
        if x == 0:
85
            res = to_digits[0]
86
        else:
87
            res = ''
88
            while x > 0:
89
                digit = x % len(to_digits)
90
                res = to_digits[digit] + res
91
                x = int(x // len(to_digits))
92
        return neg, res
93

    
94
base2 = BaseConverter(BASE2_ALPHABET)
95
base16 = BaseConverter(BASE16_ALPHABET)
96
base36 = BaseConverter(BASE36_ALPHABET)
97
base56 = BaseConverter(BASE56_ALPHABET)
98
base62 = BaseConverter(BASE62_ALPHABET)
99
base64 = BaseConverter(BASE64_ALPHABET, sign='$')