Bitwise rotation to the right

I am trying to convert this C function to Python;

typedef unsigned long var; /* Bit rotate rightwards */ var ror(var v,unsigned int bits) { return (v>>bits)|(v<<(8*sizeof(var)-bits)); } 

I tried Google for some solutions, but I can not get any of them to give the same results as here.

This is one of the solutions I found from another program;

 def mask1(n): """Return a bitmask of length n (suitable for masking against an int to coerce the size to a given length) """ if n >= 0: return 2**n - 1 else: return 0 def ror(n, rotations=1, width=8): """Return a given number of bitwise right rotations of an integer n, for a given bit field width. """ rotations %= width if rotations < 1: return n n &= mask1(width) return (n >> rotations) | ((n << (8 * width - rotations))) 

I am trying btishift key = 0xf0f0f0f0f123456 . Code C gives 000000000f0f0f12 when it is called with; ror(key, 8 << 1) and Python gives; 0x0f0f0f0f0f123456 (original input!)

+7
python bitwise-operators
source share
2 answers

Your C output does not match the function you provided. This is probably because you are not printing it correctly. This program:

 #include <stdio.h> #include <stdint.h> uint64_t ror(uint64_t v, unsigned int bits) { return (v>>bits) | (v<<(8*sizeof(uint64_t)-bits)); } int main(void) { printf("%llx\n", ror(0x0123456789abcdef, 4)); printf("%llx\n", ror(0x0123456789abcdef, 8)); printf("%llx\n", ror(0x0123456789abcdef, 12)); printf("%llx\n", ror(0x0123456789abcdef, 16)); return 0; } 

outputs the following result:

  f0123456789abcde
 ef0123456789abcd
 def0123456789abc
 cdef0123456789ab

To create the ror function in Python, I refer you to this wonderful article: http://www.falatic.com/index.php/108/python-and-bitwise-rotation

This Python 2 code produces the same output as the C program above:

 ror = lambda val, r_bits, max_bits: \ ((val & (2**max_bits-1)) >> r_bits%max_bits) | \ (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) print "%x" % ror(0x0123456789abcdef, 4, 64) print "%x" % ror(0x0123456789abcdef, 8, 64) print "%x" % ror(0x0123456789abcdef, 12, 64) print "%x" % ror(0x0123456789abcdef, 16, 64) 
+4
source share

There are different problems in your question.

Part C:

You are using a key value whose value is 64 bits ( 0x0f0f0f0f0f123456 ), but the output shows that for your compiler unsigned long is only 32 bits. So what the C code does, rotates the 32-bit value 0x0f123456 16 times, giving 0x34560f12

If you used unsigned long long (assuming it is 64 bits in your architecture, like mine), you would get 0x34560f0f0f0f0f12 (rotation 16 times out of 64 bits)

Python part:

The definition of the width between mask1 and ror is not compatible. mask1 takes the width in bits, where ror takes the width in bytes and one byte = 8 bits.

The ror function should be:

 def ror(n, rotations=1, width=8): """Return a given number of bitwise right rotations of an integer n, for a given bit field width. """ rotations %= width * 8 # width bytes give 8*bytes bits if rotations < 1: return n mask = mask1(8 * width) # store the mask n &= mask return (n >> rotations) | ((n << (8 * width - rotations)) & mask) # apply the mask to result 

So using key = 0x0f0f0f0f0f123456 you get:

 >>> hex(ror(key, 16)) '0x34560f0f0f0f0f12L' >>> hex(ror(key, 16, 4)) '0x34560f12L' 

exactly the same as pin C

+3
source share

All Articles