How to convert a number to hex number?

Ron Adam rrr at ronadam.com
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








More information about the Python-list mailing list