porting C code

Duncan Booth duncan.booth at invalid.invalid
Fri Jan 14 08:53:43 EST 2005


Lucas Raab wrote:

> Sorry, the third "byte" is what I meant. As for code samples, I hope the 
> following will work:
> 
> typedef   unsigned long int  word32 ;
> void mu(word32 *a)
> {
> int i ;
> word32 b[3] ;
> 
> b[0] = b[1] = b[2] = 0 ;
> for( i=0 ; i<32 ; i++ )
>     {
>     b[0] <<= 1 ; b[1] <<= 1 ; b[2] <<= 1 ;
>     if(a[0]&1) b[2] |= 1 ;
>     if(a[1]&1) b[1] |= 1 ;
>     if(a[2]&1) b[0] |= 1 ;
>     a[0] >>= 1 ; a[1] >>= 1 ; a[2] >>= 1 ;
>     }
> 
> a[0] = b[0] ;      a[1] = b[1] ;      a[2] = b[2] ;
> }
> 
> The "a[#]" and "b[#]" are the parts that are giving me trouble.

So far as I can tell, the function takes an array of 3 32bit values, 
reverses the order of the bits in each value, and swaps the first and last 
elements of the array. All of this seems to be being done in an attempt to 
make the process as obscure and inefficient as possible both by using 
meaningless names, and by doing both operations simultaneously.

To convert this to Python I might try something like:

rev2 = [ 0, 0x02, 0x01, 0x03 ]
rev4 = [ (lo|hi<<2) for lo in rev2 for hi in rev2 ]
rev8 = [ (lo|hi<<4) for lo in rev4 for hi in rev4 ]

def rev32(n):
    '''Reverse the low 32bits of an integer'''
    return (rev8[(n>>24)&0xff]|
            (rev8[(n>>16)&0xff]<<8)|
            (rev8[(n>>8)&0xff]<<16)|
            (rev8[n&0xff]<<24))

def mu(a):
    '''Reverse the bit order of a list of 32bit integers while
       also reversing the list itself'''
    return [rev32(n) for n in reversed(a)]

print [hex(n) for n in mu([0x10203040, 0x50607080, 0x90a0b0c0])]

Although if 'a' really is just being used as a 96 bit integer I could add a 
96 bit variant of the reversal function and use it directly:

def rev96(n):
    '''Reverse the low 96bits of an integer'''
    return rev32(n>>64)|(rev32(n>>32)<<32)|(rev32(n)<<64)

print hex(rev96(0x102030405060708090a0b0c0L))




More information about the Python-list mailing list