所以我有一个python脚本,它使用pyserial库通过串口将文件发送到另一台计算机。我写了一些脚本来计算文件的md5校验和,然后我遇到了一些问题。
实施例: 我发送了一个名为third.txt的简单文件,其中包含数字1到10的列表。简单文件,没什么花哨或大。发送前文件的校验和与在另一台计算机上传输后的文件校验和完全不同,即使文件明显相同。
我通过简单地通过USB移动文件并以这种方式进行校验和计算来检查我的代码是否有问题。这次它奏效了。
为什么会发生这种情况以及如何解决这个问题?
这是发送前的校验和代码。这不是确切的代码,但基本上就是我所做的。
<<Code that waits for command from client>>
with open(file_loc) as file_to_read:
data = file_to_read.read()
md5a = hashlib.md5(data).hexdigest()
ser.write('\n' + md5a + '\n')
这是我发送后的校验和代码。
with open(file_loc) as file_to_read:
data = file_to_read.read()
md5b = hashlib.md5(data).hexdigest()
print('Sending Checksum Command')
ser.write("\n<<SENDCHECKSUM>>\n")
md5a = ser.readline()
print(md5a)
print(md5b)
if md5a == md5b:
print("Correct File Transmission")
else:
print("The checksum indicated incorrect file transmission, please check.")
ser.flush()
答案 0 :(得分:6)
是的,以文本模式打开文件可能会导致读取不同的数据,因为换行符将从平台本机格式转换为\n
。因此,在Windows和POSIX平台上读取时,包含\r\n
的文件将为您提供不同的校验和。
以二进制模式打开文件:
with open(file_loc, 'rb') as file_to_read:
请注意,写入文件时也是如此。如果您使用\n
行结尾从POSIX系统接收数据,并将其写入在Windows上以文本模式打开的文件,则最终会在写入的文件中以\r\n
行结尾
如果您使用的是Python 3,则会使问题复杂化。在文本模式下打开文件时,您将数据从已编码的字节转换为已解码的Unicode值。使用什么编解码器也可能因OS而异,甚至从机器到机器也不同。默认值是locale-defined(使用locale.getpreferredencoding(False)
),只要数据可以通过默认语言环境解码,您就可以使用不同的编解码器获取非常不同的结果。您确实希望通过明确设置它来确保使用相同的编解码器,或者更好的是,以二进制模式打开文件。
由于hashlib
要求您提供字节字符串,因此在尝试计算摘要时这不是问题(您已经遇到了这个问题,至少不得不考虑那里的编解码器),但是这也适用于文件传输; 将写入文本文件会将数据编码为默认编解码器。