# How to convert a number to hex number?

Wed Nov 9 01:42:45 CET 2005

```
Bengt Richter wrote:
> On 08 Nov 2005 08:07:34 -0800, Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote:
>
>
>>"dcrespo" <dcrespo at gmail.com> writes:
>>
>>>>>>hex(255)[2:]
>>>
>>>'ff'
>>
>>'%x'%255 is preferable since the format of hex() output can vary.  Try hex(33**33).
>
>
> Not to mention (#@%*!-pletive deleted ;-)
>
>  >>> hex(-255)[2:]
>  'xff'
>  >>> hex(-255)
>  '-0xff'
>  >>> hex(-255&0xff)
>  '0x1'
>
> Regards,
> Bengt Richter

I just happen to have been playing around with converting bases the last
couple of days.  (idonowhy) ;-)

Oh yeah,  I was thinking of using base62 to generate non-repeating id
strings and wanted to try it out.

A few nits ...

* Existing hex strings need to be converted to uppercase to work
correctly with base2int() below.

* The reason I placed capitals before lower case is so sequences (in
higher bases) will sort correctly.

* The base_iter (or generator) probably needs more work. I'm not sure
what the best behavior should be for it, but iterating a string is
faster than converting to int and back.

I doubt I can make these significantly faster at this point.  Using
dictionary lookups really helped a lot going both ways.

Cheers,
Ron

import string
BaseDigits = sorted(list(string.digits + string.ascii_letters))
BaseDigitIndex = dict([(y,x) for (x,y) in enumerate(BaseDigits)])

def int2base(n, base):
"""
Convert an integer to a string of base 2 to 62.
"""
if not 1 < base < 63:
raise ValueError, "base out of range"
if n < 0:
sign = '-'
n = abs(n)
else:
sign = ''
s = ''
while 1:
s = BaseDigits[n % base] + s
n //= base
if n == 0: return sign + s

def base2int(s, base):
"""
Convert a string base 2 to 62 to an integer
"""
if not 1 < base < 63:
raise ValueError, "base out of range"
if s[0] == '-':
sign = -1
s = s[1:]
else:
sign = 1
n = 0
i = lens = len(s)-1
for digit in s:
n += BaseDigitIndex[s[i]] * base ** (lens-i)
i -= 1
return n * sign

def base_iter(base=None, start='0'):
"""
Generate a sequence of strings in base 2 to 62
"""
if not 1 < base < 63:
raise ValueError, "base out of range"
digits = BaseDigits[:base]
incriment = dict(zip(digits, digits[1:]+digits[:1]))
def nBase():
value = start
maxindex = 0
while 1:
yield value
i = maxindex
while i >= 0:
value = value[:i] + incriment[value[i]] + value[i+1:]
if value[i] != '0':
break
i -= 1
else:
value = '1' + value
maxindex += 1
return nBase().next

```