我正在尝试将此C函数转换为Python;
typedef unsigned long var;
/* Bit rotate rightwards */
var ror(var v,unsigned int bits) {
return (v>>bits)|(v<<(8*sizeof(var)-bits));
}
我已经尝试使用谷歌搜索一些解决方案,但我似乎无法让他们中的任何一个给出与此处相同的结果。
这是我从另一个程序中找到的一个解决方案;
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)))
我正在尝试btishift key = 0xf0f0f0f0f123456
。 C代码在调用时给出000000000f0f0f12
; ror(key, 8 << 1)
和Python给出; 0x0f0f0f0f0f123456
(原始输入!)
答案 0 :(得分:5)
您的C输出与您提供的功能不匹配。这可能是因为您没有正确打印它。这个计划:
#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;
}
产生以下输出:
f0123456789abcde ef0123456789abcd def0123456789abc cdef0123456789ab
要在Python中生成ror函数,请参阅这篇优秀的文章:http://www.falatic.com/index.php/108/python-and-bitwise-rotation
这个Python 2代码产生与上面C程序相同的输出:
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)
答案 1 :(得分:3)
您的问题存在不同的问题。
使用64位值(0x0f0f0f0f0f123456
)的key值,但输出显示编译器无符号long只有32位宽。那么C代码所做的是将32位值0x0f123456
旋转16次,给出0x34560f12
如果您使用过unsigned long long
(假设您的架构上是64位,就像我的那样),那么您将获得0x34560f0f0f0f0f12
(64位旋转16次)
mask1和ror之间的宽度定义不一致。 mask1
取宽度(以位为单位),其中ror取宽度(以字节为单位),1字节= 8位。
ror
函数应为:
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
使用key = 0x0f0f0f0f0f123456
的方式,你得到:
>>> hex(ror(key, 16))
'0x34560f0f0f0f0f12L'
>>> hex(ror(key, 16, 4))
'0x34560f12L'
与C输出完全相同
答案 2 :(得分:2)
我在Python中找到的最短方法: (请注意,这仅适用于整数作为输入)
def ror(n,rotations,width):
return (2**width-1)&(n>>rotations|n<<(width-rotations))
答案 3 :(得分:0)
def rotation_value(value, rotations, widht=32):
""" Return a given number of bitwise left or right rotations of an interger
value,
for a given bit field widht.
if rotations == -rotations:
left
else:
right
"""
if int(rotations) != abs(int(rotations)):
rotations = widht + int(rotations)
return (int(value)<<(widht-(rotations%widht)) | (int(value)>>(rotations%widht))) & ((1<<widht)-1)
答案 4 :(得分:0)
我知道它已经快6岁了
我总是发现使用字符串切片比按位操作更容易。
def rotate_left(x, n):
return int(f"{x:032b}"[n:] + f"{x:032b}"[:n], 2)
def rotate_right(x, n):
return int(f"{x:032b}"[-n:] + f"{x:032b}"[:-n], 2)