【发布时间】:2014-09-09 11:03:57
【问题描述】:
我在为一个奇怪的协议计算文件校验和之类的东西时遇到了麻烦,我正在尝试移植到 python。
校验和是一个 4 字节无符号整数,是文件中所有 4 字节无符号整数相加的结果。例如,假设以下文件(注意,真实的文件大约为 16MB):
ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0
ef ee ed ec eb ea e9 e8 e7 e6
使用我的实现(见下文),计算如下:
0xfffefdfc + 0xfbfaf9f8 + 0xf7f6f5f4 + 0xf3f2f1f0 + 0xefeeedec + 0xebeae9e8 + 0xe7e60000 = 0x6aba3b7ac
但是,应该是0xaba3b7ac
我尝试过这样做:
import mmap
import struct
# Prepare file
file = open("file.bin", 'rb')
map = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
# Calculate checksum
checksum = 0
while (map.tell() < map.size()):
checksum += struct.unpack('>I', map.read(4))[0]
print "checksum: ", checksum
# Close file.
map.close()
file.close()
但我发现了两个问题。
- 首先,输出数太大。我需要一个 4 字节的数字。
使用前面的代码,典型测试文件的输出类似于
0x165c0458b224ae但它应该类似于0xcaac5458(一个 4 字节无符号 整数)。 - 我的方法很慢。原始代码(用 C 编写)确实 计算速度更快。
我真的坚持这一点,所以任何帮助将不胜感激。
在此先感谢,并为我的英语不好感到抱歉。
更新:
第一个问题由 Serge Ballesta 解决。解决方案是在打印校验和之前添加以下行:
checksum &= 0xffffffff
但是计算仍然很慢。我想要一个快速的解决方案,但我不知道该怎么做。
【问题讨论】:
-
这个是一个校验和,但它不是一个CRC,所以在你的代码中使用这个术语不是一个好主意。
-
文件是否太大而无法放入内存?为什么要使用 mmap 而不是
array模块或更好的numpy(如果可用)? -
你应该在 read-binary 'rb' 中打开文件。
-
你不能为 C 代码编写一个 Python 绑定吗? stackoverflow.com/questions/10202306/…
-
输入文件很大 (16 MB)。这就是使用 mmap 的原因。另外,我不能使用原始的 C 代码,因为它是在 windows machin 中编译的,并且此代码适用于 linux 机器。
标签: python