Skip to content

Instantly share code, notes, and snippets.

@blech
Created April 13, 2009 13:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save blech/94454 to your computer and use it in GitHub Desktop.
Save blech/94454 to your computer and use it in GitHub Desktop.
Flickr rev-canonical reverse engineering
"""
Convert numbers from base 10 integers to base X strings and back again.
Sample usage:
>>> base20 = BaseConverter('0123456789abcdefghij')
>>> base20.from_decimal(1234)
'31e'
>>> base20.from_decimal('31e')
1234
Originally posted to http://www.djangosnippets.org/snippets/1431/
by Simon Willison
"""
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
#!/usr/bin/python
# trying to figure out the right base58 string for Flickr
# rev-canonical shortening from ID
# *nearly* there....
# yes, this should be written as a test really
import baseconv
# http://www.djangosnippets.org/snippets/1431/ - baseconv.py
base58 = baseconv.BaseConverter('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ')
# thank you kellan! http://www.flickr.com/groups/api/discuss/72157616713786392/
hashes = {3429289555: '6e3w38',
3368: '215',
74: '2h',
75: '2i',
94: '2C',
88: '2w',
195102: 'ZZQ',
1253576: '7qDo',
177: '44',
193: '4k',
195: '4n',
}
for dec in hashes.keys():
print dec,
print base58.from_decimal(dec),
print hashes[dec]
# results:
# 3429289555 6e31iZ 6e3w38 # <--- not right: overflow issue with integer?
# 1253576 7qDo 7qDo
# 195102 ZZQ ZZQ
# 3368 215 215
# 195 4n 4n
# 193 4k 4k
# 177 44 44
# 94 2C 2C
# 88 2w 2w
# 75 2i 2i
# 74 2h 2h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment