1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/python/base36.py Wed Jun 09 15:12:43 2010 -0400
1.3 @@ -0,0 +1,59 @@
1.4 +"""
1.5 +Base36 Encoder/Decoder
1.6 +by Mike Crute (mcrute@gmail.com) on August 26, 2008
1.7 +This code has been placed in the public domain.
1.8 +
1.9 +This is just a simple module to do base36 encoding and decoding. Theoretically
1.10 +you could use this for any base < 2 <= 36 && base != 32 but I only really need
1.11 +to have base36 so its an exercise for the reader to implement other base
1.12 +conversions.
1.13 +
1.14 +This won't work for base32 at least not if you want your output to work with other
1.15 +base32 decoders because RFC4648 skips 0 and 1 (2-7A-Z) and this module doesn't
1.16 +account for that. Bah...
1.17 +
1.18 +The only reason I wrote this is because the other implementations of base
1.19 +conversion relied upon hard coded lists of characters and that really
1.20 +bothered me, plus didn't quite give me the flexibility I was looking for.
1.21 +"""
1.22 +
1.23 +def _codec(str_in, base_from=36, base_to=10):
1.24 + """Convert a number to/from a base less than or equal to 36.
1.25 + Converts a string or number to or from a base without using static
1.26 + lookup tables.
1.27 + """
1.28 + # Some ASCII Codes
1.29 + ASCII = { "0": 48, "9": 57, "A": 65, "Z": 90 }
1.30 +
1.31 + # There are 8 characters between 9 and A
1.32 + from_digits = [chr(x) for x in range(ASCII["0"], ASCII["9"] + 8 + base_from)
1.33 + if (x >= ASCII["0"] and x <= ASCII["9"]) or
1.34 + (x >= ASCII["A"] and x <= ASCII["Z"])][:base_from]
1.35 +
1.36 + to_digits = [chr(x) for x in range(ASCII["0"], ASCII["9"] + 8 + base_to)
1.37 + if (x >= ASCII["0"] and x <= ASCII["9"]) or
1.38 + (x >= ASCII["A"] and x <= ASCII["Z"])][:base_to]
1.39 +
1.40 + x = long(0)
1.41 + for digit in str(str_in).upper():
1.42 + x = x * len(from_digits) + from_digits.index(digit)
1.43 +
1.44 + result = ""
1.45 + # This is going to assemble our number in reverse order
1.46 + # so we'll have to fix it before we return it
1.47 + while x > 0:
1.48 + result += to_digits[x % len(to_digits)]
1.49 + x /= len(to_digits)
1.50 +
1.51 + return result[::-1]
1.52 +
1.53 +
1.54 +def base36encode(str_in):
1.55 + """Base36 encode a base10 number.
1.56 + """
1.57 + return _codec(str_in, 10, 36)
1.58 +
1.59 +def base36encode(str_in):
1.60 + """Get a base10 number for a base36 number.
1.61 + """
1.62 + return long(_codec(str_in, 36, 10))
1.63 \ No newline at end of file