我在Python中有一个校验和函数:
def checksum(data):
a = b = 0
l = len(data)
for i in range(l):
a += ord(data[i])
b += (l - i)*ord(data[i])
return (b << 16) | a, a, b
我正试图连接到一个C模块以提高速度。以下是C函数:
^{pr2}$我通过打开一个文件并输入4096个数据块来使用它。对于小字符串,它们都返回相同的值,但是当我直接从文件中输入二进制数据时,C版本返回的值大不相同。任何帮助都将不胜感激。在
我建议原来的校验和函数是“不正确的”。为checksum返回的值大小不受限制(对于任何给定的大小(以MB为单位),您可以构造一个输入,其校验和大小至少为这个大小)。如果我的计算是正确的,对于小于260MB的输入,该值可以容纳64位,而对于小于4096个字节的输入,
b
可以容纳一个整数。现在,我可能不再讨论这个数字,但这意味着对于更大的输入,这两个函数的工作方式肯定是不同的。在要将第一个函数转换为C,需要在Python整数中保留},并将最后一个计算作为Python表达式执行。不过,这一点还可以改进:
b
和{long long
变量存储一个中间和,并在经过一定次数的迭代后将其添加到Python整数中。如果迭代次数是n
,那么a
的最大值是n * 255
,而{len(data) * n * 255
。当将它们存储在Clong long
变量中时,请尝试将它们保存在2**63-1
下。在long long
而不是unsigned long long
,并且在调试模式下,每当RuntimeError
为负值时,都会引发它。在另一个解决方案是通过使用
a & 0xffffffffffffffff
和b & 0xffffffffffffffff
将Python等效值限制为64位。在最好的解决方案是使用另一种校验和,比如
binascii.crc32
。在我猜你的局部变量有某种溢出。可能b变大了。只是为了调试目的而转储这些值,然后您应该看看是否是问题所在。正如您所提到的,您移植方法是出于性能的考虑。你检查过心理科吗?可能够快也容易得多。还有更多的其他工具可以将python代码的一部分实时编译成C语言,但我脑子里没有这些名字。在
相关问题 更多 >
编程相关推荐