【发布时间】:2022-02-02 22:46:14
【问题描述】:
import ctypes
def main():
key = 0xDEADBEEF
print(f"({type(key)}) {key = }")
key = key * 5 + 2
print(f"({type(key)}) {key = }")
key = key * 5 + 2
print(f"({type(key)}) {key = }")
key = key * 5 + 2
print(f"({type(key)}) {key = }")
key = ctypes.c_uint(0xDEADBEEF)
print(f"({type(key)}) {key.value = }")
key = ctypes.c_uint(key.value * 5 + 2)
print(f"({type(key)}) {key.value = }")
key = ctypes.c_uint(key.value * 5 + 2)
print(f"({type(key)}) {key.value = }")
key = ctypes.c_uint(key.value * 5 + 2)
print(f"({type(key)}) {key.value = }")
if __name__ == '__main__':
main()
如果你运行它,它会输出:
(<class 'int'>) key = 3735928559
(<class 'int'>) key = 18679642797
(<class 'int'>) key = 93398213987
(<class 'int'>) key = 466991069937
(<class 'ctypes.c_ulong'>) key.value = 3735928559
(<class 'ctypes.c_ulong'>) key.value = 1499773613
(<class 'ctypes.c_ulong'>) key.value = 3203900771
(<class 'ctypes.c_ulong'>) key.value = 3134601969
为什么它在 python 上不断增长?
有没有什么方法可以在不使用 ctypes 的情况下复制 C 的功能,或者它只是 python 的工作原理?
编辑:
好的,感谢@n.1.8e9-where's-my-sharem,我了解到在 C 语言中 uint get 的上限为 32 位,为了在 python 中获得同样的效果,我们可以使用 number modulo 2^32
def main():
key_a = 0xDEADBEEF
key_b = uint32(0xDEADBEEF)
printBinary(key_a)
printBinary(key_b)
print('--')
key_a = key_a * 5 + 2
key_b = uint32(key_b * 5 + 2)
printBinary(key_a)
printBinary(key_b)
print('--')
key_a = key_a * 5 + 2
key_b = uint32(key_b * 5 + 2)
printBinary(key_a)
printBinary(key_b)
print('--')
key_a = key_a * 5 + 2
key_b = uint32(key_b * 5 + 2)
printBinary(key_a)
printBinary(key_b)
print('--')
key_a = key_a * 5 + 2
key_b = uint32(key_b * 5 + 2)
printBinary(key_a)
printBinary(key_b)
def printBinary(argument) -> None:
binary_repr = f"{argument:<15} in binary {argument:>43b}"
print(binary_repr)
def uint32( n, num_bits=32):
return n % (2 ** num_bits)
if __name__ == '__main__':
main()
所以如果我们运行之前的代码,我们会得到:
3735928559 in binary 11011110101011011011111011101111
3735928559 in binary 11011110101011011011111011101111
--
18679642797 in binary 10001011001011001001011101010101101
1499773613 in binary 1011001011001001011101010101101
--
93398213987 in binary 1010110111110111101111010010101100011
3203900771 in binary 10111110111101111010010101100011
--
466991069937 in binary 110110010111010110101100011101011110001
3134601969 in binary 10111010110101100011101011110001
--
2334955349687 in binary 100001111110100110001011110010011010110111
2788107959 in binary 10100110001011110010011010110111
我们可以看到,使用函数uint32,我们可以保留密钥的前 32 位。
【问题讨论】:
-
“为什么它在 python 中不断增长?” - 更好的问题是“为什么它不在 C 中不断增长?”。跨度>
-
如果你想要运算模 2^n,也许添加显式减少模 2^n?
-
@n.1.8e9-where's-my-sharem。我对python中的数学运算不是很了解,我只是想在python中复制一个C#程序。
-
@n.1.8e9-where's-my-sharem。好的,所以
n % (2 ** num_bits)有效,num_bits是 32,因为 uint 是一个 32 位无符号整数,你认为你可以在答案中解释一下以便我接受吗? -
@n.1.8e9-where's-my-sharem。如果我理解正确,我得到的数字在我的第一种情况下不断增加并且只保留前 32 位?