aboutsummaryrefslogtreecommitdiffstats
path: root/src/shorturls/baseconv.py
diff options
context:
space:
mode:
authorJacob Kaplan-Moss2009-04-12 16:25:05 -0500
committerJacob Kaplan-Moss2009-04-12 16:25:05 -0500
commitb5ee253b28673fcfad49f09d9d2687e86ed520b7 (patch)
tree32f3f5939bf8d69503f443573414ea80567d095e /src/shorturls/baseconv.py
parent4391a39ee4cde31ff9c9a56cd8d452b934136b4e (diff)
downloaddjango-shorturls-b5ee253b28673fcfad49f09d9d2687e86ed520b7.tar.bz2
Added a working shorturl redirect view, with tests.
Diffstat (limited to 'src/shorturls/baseconv.py')
-rw-r--r--src/shorturls/baseconv.py65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/shorturls/baseconv.py b/src/shorturls/baseconv.py
new file mode 100644
index 0000000..9012441
--- /dev/null
+++ b/src/shorturls/baseconv.py
@@ -0,0 +1,65 @@
+"""
+Convert numbers from base 10 integers to base X strings and back again.
+
+Original: http://www.djangosnippets.org/snippets/1431/
+
+Sample usage:
+
+>>> base20 = BaseConverter('0123456789abcdefghij')
+>>> base20.from_decimal(1234)
+'31e'
+>>> base20.from_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, hex, base62]:
+ for i in nums:
+ assert i == bin.to_decimal(bin.from_decimal(i)), '%s failed' % i
+