Gustavo Picon is sharing code with you

Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.

Don't show this again

tabo / numconv

Python library to convert strings to numbers and numbers to strings. Docs: http://docs.tabo.pe/numconv/tip/

Clone this repository (size: 168.1 KB): HTTPS / SSH
hg clone https://bitbucket.org/tabo/numconv
hg clone ssh://hg@bitbucket.org/tabo/numconv

numconv / numconv.py

commit
dac783631be1
parent
882b6d180761
branch
default
tags
2.1

newline

1
a507bcdecc11
"""Convert strings to numbers and numbers to strings.
2
a035ba7fb21b
3
a507bcdecc11
Gustavo Picon
4
a507bcdecc11
http://code.tabo.pe/numconv/
5
ce5fa2cc27b2
6
a035ba7fb21b
"""
7
a035ba7fb21b
8
bbef845a6732
9
882b6d180761
__version__ = '2.1.0'
10
a035ba7fb21b
11
a035ba7fb21b
# from april fool's rfc 1924
12
a035ba7fb21b
BASE85 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' \
13
a035ba7fb21b
         '!#$%&()*+-;<=>?@^_`{|}~'
14
a035ba7fb21b
15
a035ba7fb21b
# rfc4648 alphabets
16
a035ba7fb21b
BASE16 = BASE85[:16]
17
a035ba7fb21b
BASE32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
18
a035ba7fb21b
BASE32HEX = BASE85[:32]
19
a035ba7fb21b
BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
20
a035ba7fb21b
BASE64URL = BASE64[:62] + '-_'
21
a035ba7fb21b
22
ce5fa2cc27b2
# http://en.wikipedia.org/wiki/Base_62 useful for url shorteners
23
ce5fa2cc27b2
BASE62 = BASE85[:62]
24
ce5fa2cc27b2
25
6ae83e41ff11
26
6ae83e41ff11
class NumConv(object):
27
6ae83e41ff11
    """Class to create converter objects.
28
b27cf772ba32
29
6ae83e41ff11
        :param radix: The base that will be used in the conversions.
30
6ae83e41ff11
           The default value is 10 for decimal conversions.
31
6ae83e41ff11
        :param alphabet: A string that will be used as a encoding alphabet.
32
b27cf772ba32
           The length of the alphabet can be longer than the radix. In this
33
b27cf772ba32
           case the alphabet will be internally truncated.
34
b27cf772ba32
35
6ae83e41ff11
           The default value is :data:`numconv.BASE85`
36
b27cf772ba32
37
6ae83e41ff11
        :raise TypeError: when *radix* isn't an integer
38
6ae83e41ff11
        :raise ValueError: when *radix* is invalid
39
6ae83e41ff11
        :raise ValueError: when *alphabet* has duplicated characters
40
6ae83e41ff11
    """
41
b27cf772ba32
42
6ae83e41ff11
    def __init__(self, radix=10, alphabet=BASE85):
43
6ae83e41ff11
        "basic validation and cached_map storage"
44
6ae83e41ff11
        if int(radix) != radix:
45
6ae83e41ff11
            raise TypeError('radix must be an integer')
46
6ae83e41ff11
        if not 2 <= radix <= len(alphabet):
47
6ae83e41ff11
            raise ValueError('radix must be >= 2 and <= %d' % (
48
6ae83e41ff11
                len(alphabet), ))
49
6ae83e41ff11
        self.radix = radix
50
6ae83e41ff11
        self.alphabet = alphabet
51
6ae83e41ff11
        self.cached_map = dict(zip(self.alphabet, range(len(self.alphabet))))
52
6ae83e41ff11
        if len(self.cached_map) != len(self.alphabet):
53
6ae83e41ff11
            raise ValueError("duplicate characters found in '%s'" % (
54
6ae83e41ff11
                self.alphabet, ))
55
6ae83e41ff11
56
6ae83e41ff11
    def int2str(self, num):
57
6ae83e41ff11
        """Converts an integer into a string.
58
b27cf772ba32
59
6ae83e41ff11
        :param num: A numeric value to be converted to another base as a
60
6ae83e41ff11
                    string.
61
b27cf772ba32
62
6ae83e41ff11
        :rtype: string
63
b27cf772ba32
64
6ae83e41ff11
        :raise TypeError: when *num* isn't an integer
65
6ae83e41ff11
        :raise ValueError: when *num* isn't positive
66
6ae83e41ff11
        """
67
6ae83e41ff11
        if int(num) != num:
68
6ae83e41ff11
            raise TypeError('number must be an integer')
69
6ae83e41ff11
        if num < 0:
70
6ae83e41ff11
            raise ValueError('number must be positive')
71
6ae83e41ff11
        radix, alphabet = self.radix, self.alphabet
72
6ae83e41ff11
        if radix in (8, 10, 16) and \
73
6ae83e41ff11
                alphabet[:radix].lower() == BASE85[:radix].lower():
74
6ae83e41ff11
            return ({8: '%o', 10: '%d', 16: '%x'}[radix] % num).upper()
75
6ae83e41ff11
        ret = ''
76
6ae83e41ff11
        while True:
77
6ae83e41ff11
            ret = alphabet[num % radix] + ret
78
6ae83e41ff11
            if num < radix:
79
6ae83e41ff11
                break
80
6ae83e41ff11
            num //= radix
81
6ae83e41ff11
        return ret
82
b27cf772ba32
83
6ae83e41ff11
    def str2int(self, num):
84
6ae83e41ff11
        """Converts a string into an integer.
85
b27cf772ba32
86
6ae83e41ff11
        If possible, the built-in python conversion will be used for speed
87
6ae83e41ff11
        purposes.
88
b27cf772ba32
89
6ae83e41ff11
        :param num: A string that will be converted to an integer.
90
b27cf772ba32
91
6ae83e41ff11
        :rtype: integer
92
b27cf772ba32
93
6ae83e41ff11
        :raise ValueError: when *num* is invalid
94
6ae83e41ff11
        """
95
6ae83e41ff11
        radix, alphabet = self.radix, self.alphabet
96
6ae83e41ff11
        if radix <= 36 and alphabet[:radix].lower() == BASE85[:radix].lower():
97
6ae83e41ff11
            return int(num, radix)
98
6ae83e41ff11
        ret = 0
99
6ae83e41ff11
        lalphabet = alphabet[:radix]
100
6ae83e41ff11
        for char in num:
101
6ae83e41ff11
            if char not in lalphabet:
102
6ae83e41ff11
                raise ValueError("invalid literal for radix2int() with radix "
103
6ae83e41ff11
                                 "%d: '%s'" % (radix, num))
104
6ae83e41ff11
            ret = ret * radix + self.cached_map[char]
105
6ae83e41ff11
        return ret
106
a035ba7fb21b
107
a035ba7fb21b
108
a035ba7fb21b
def int2str(num, radix=10, alphabet=BASE85):
109
6ae83e41ff11
    "helper for quick base conversions from integers to strings"
110
6ae83e41ff11
    return NumConv(radix, alphabet).int2str(num)
111
0d8c44c9fa40
112
b27cf772ba32
113
a035ba7fb21b
def str2int(num, radix=10, alphabet=BASE85):
114
6ae83e41ff11
    "helper for quick base conversions from strings to integers"
115
6ae83e41ff11
    return NumConv(radix, alphabet).str2int(num)