Python计算文件的校验和用于奇怪的p

2024-04-25 01:54:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我在为一个奇怪的协议计算一个文件的校验和之类的东西时遇到了困难,我试图将它移植到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

在我的实现中(见下文),计算如下:

^{pr2}$

但是,它应该是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()

但我看到了两个问题。在

  1. 首先,输出数量太大。我需要一个4字节的数字。 对于前面的代码,典型测试文件的输出如下所示 0x165c0458b224ae但它应该是0xcaac5458(一个4字节的无符号 整数)。在
  2. 我的方法很慢。原始代码(用C编写)可以 计算速度快得多。在

我真的很难接受,所以任何帮助都会很感激的。在

提前谢谢,很抱歉我的英语不好。在


更新:

第一个问题由谢尔盖·巴列斯塔解决了。解决方案是在打印校验和之前添加以下行:

checksum &= 0xffffffff

但是计算仍然很慢。我不想知道怎么解决。在


Tags: 文件代码import协议mapclose字节符号
2条回答

我觉得你有问题,但不是你描述的那些。在

从任意长的数字传递到4字节的整数就像n4b = n & 0x0FFFFFFFF

我不明白为什么为Windows机器编写的C源代码不能在Unix机器上编译。在

也就是说,6293623225328814 & 0xFFFFFFFF以六边形给出{}或{},这不是你预期的结果。我想你有问题。你应该先用小端和大端来计算它,以知道选择哪个。在

# Calculate checksum
checksum_be = 0
checksum_le = 0
while (map.tell() < map.size()):
    checksum_be += struct.unpack('>I', map.read(4))[0]
    checksum_le += struct.unpack('<I', map.read(4))[0]
checksum_be &= 0x0FFFFFFFF
checksum_le &= 0x0FFFFFFFF

print "checksums: ", checksum_be, checksum_le

一种方法是使用array模块并将所有四个字节加载到内存中,求和,然后强制返回到4字节(正如Serge已经提到的)。在

import os
from array import array

#with open('data.bin', 'wb') as fout:
#   fout.write(os.urandom(16800000))

with open('data.bin', 'rb') as fin:
    arr = array('L')
    arr.fromfile(fin, 16800000 / 4)
    arr.byteswap()
    checksum = sum(arr) & 0xFFFFFFFF

在我的笔记本上花了不到一秒钟的时间。。。不知道你想让它跑多快。。。在

相关问题 更多 >