Python:为一个奇怪的协议计算文件的校验和

Python:为一个奇怪的协议计算文件的校验和,python,Python,我在计算一个文件的校验和之类的东西时遇到了麻烦,我正在尝试将一个奇怪的协议移植到python 校验和是一个4字节无符号整数,它是文件中所有4字节无符号整数相加的结果。例如,假设以下文件(请注意,实际文件大约为16MB): 在我的实现中(见下文),计算如下: 0xfffefdfc + 0xfbfaf9f8 + 0xf7f6f5f4 + 0xf3f2f1f0 + 0xefeeedec + 0xebeae9e8 + 0xe7e60000 = 0x6aba3b7ac 但是,它应该是0xaba3b7ac

我在计算一个文件的校验和之类的东西时遇到了麻烦,我正在尝试将一个奇怪的协议移植到python

校验和是一个4字节无符号整数,它是文件中所有4字节无符号整数相加的结果。例如,假设以下文件(请注意,实际文件大约为16MB):

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

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字节整数的传递非常简单,如
n4b=n&0x0ffffff

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

也就是说,
6293623225328814&0xFFFFFFFF
以六进制给出
1488069806
0x58b224ae
,这不是您期望的结果。我想你有一个问题。你应该先用小端和大端计算它,知道选择哪个

# 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
#计算校验和
校验和_be=0
校验和=0
而(map.tell()I',map.read(4))[0]

checksum_le+=struct.unpack(“我认为您有问题,但不是您描述的问题

从任意长数字到4字节整数的传递非常简单,如
n4b=n&0x0ffffff

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

也就是说,
6293623225328814&0xFFFFFFFF
给出了
1488069806
0x58b224ae
的六边形,这不是您期望的结果。我想您有和端的问题。您应该首先在小端和大端计算它,以知道选择哪个

# 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
#计算校验和
校验和_be=0
校验和=0
而(map.tell()I',map.read(4))[0]

checksum_le+=struct.unpack(“我认为您有问题,但不是您描述的问题

从任意长数字到4字节整数的传递非常简单,如
n4b=n&0x0ffffff

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

也就是说,
6293623225328814&0xFFFFFFFF
给出了
1488069806
0x58b224ae
的六边形,这不是您期望的结果。我想您有和端的问题。您应该首先在小端和大端计算它,以知道选择哪个

# 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
#计算校验和
校验和_be=0
校验和=0
而(map.tell()I',map.read(4))[0]

checksum_le+=struct.unpack(“我认为您有问题,但不是您描述的问题

从任意长数字到4字节整数的传递非常简单,如
n4b=n&0x0ffffff

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

也就是说,
6293623225328814&0xFFFFFFFF
给出了
1488069806
0x58b224ae
的六边形,这不是您期望的结果。我想您有和端的问题。您应该首先在小端和大端计算它,以知道选择哪个

# 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
#计算校验和
校验和_be=0
校验和=0
而(map.tell()I',map.read(4))[0]

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


在我的笔记本电脑上只花了不到一秒钟的时间…不知道你想让它快多少…

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


在我的笔记本电脑上只花了不到一秒钟的时间…不知道你想让它快多少…

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


在我的笔记本电脑上只花了不到一秒钟的时间…不知道你想让它快多少…

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


在我的笔记本电脑上只需不到一秒钟的时间…不确定您希望它运行得快多少…

这是一个校验和,但不是CRC,因此在代码中使用该术语不是一个好主意。文件是否太大而无法放入内存?为什么要使用mmap而不是
数组
模块或更好的
numpy
,如果它可用的话?您应该这样做以读取二进制文件“rb”打开文件。难道不能为C代码编写Python绑定吗?输入文件很大(16MB)。这就是使用mmap的原因。此外,我不能使用原始C代码,因为它是在windows机器中编译的,并且此代码是针对linux机器的。这是一个校验和,但不是CRC,因此在代码中使用该术语不是一个好主意。文件是否太大而无法放入内存?为什么要使用mmap而不是
数组
模块或更好的
numpy
如果可用的话?您应该以读取二进制“rb”打开文件。您不能为C代码编写Python绑定吗?输入文件很大(16 MB)。这就是使用mmap的原因。此外,我不能使用原始C代码,因为它是在windows机器中编译的,而此代码是针对linux机器的。这是一个校验和,但不是CRC,因此在代码中使用该术语不是一个好主意。文件是