验证 python 中的 zip 文件
Verify zip files in python
我需要验证 python 应用程序生成的 zip 文件的内容。我希望每次我们 运行 应用程序时,它都会生成具有相同内容的完全相同的 zip 文件(当提供相同的输入时)。关于内容,我指的只是被压缩文件的内容,而不是这些文件或 zip 文件的元信息。
问题是 zip 文件保留了一些元信息,例如每个文件的创建时间,每次 运行 应用程序时这些信息都不同。不幸的是,这些 zip 文件可能包含数百万个小文件,这使得提取和计算每个小文件的哈希值变得非常不愉快。
做这样的测试有什么好的方法?我一直在尝试 hashlib 中的 "md5" 方法,即将 zip 文件的 md5 值与先前计算的值进行比较。但是,每次 运行 应用程序的 md5 值都不同,因为元信息不同。知道我该怎么做这个测试吗?如果可能的话,我不介意使用相同的元信息来提取和重新压缩它。请注意,zip 文件包含多层目录。
据我了解,您正在尝试编写自动化测试来验证您的 zip 文件的内容是否符合您的预期。
md5 似乎是一个很好的候选者。现在,如果您在 zip 文件中有与时间相关的数据,我建议您为此使用 https://github.com/spulec/freezegun。它被设计为 "suspend" 时间,以便所有对 datetime
函数(now()
、today()
...)的调用都将 return 一个已知值。你可以这样做:
from freezegun import freeze_time
def test_zipping():
with freeze_time("2012-01-14 12:34:56"):
zipfile = create_zip_file(data)
md5 = hashlib.md5()
with open(zipfile_name) , "rb" ) as f:
data = f.read(block_size)
if not data:
break
md5.update(data)
assert md5.digest() == expected_md5_value
有了这个,您应该能够从测试中消除与时间相关的调用的随机性。
(受 Get MD5 hash of big files in Python 启发,因为您的 zip 文件似乎足够大)
我喜欢 Laurent S 的基本想法,以确保您在 运行 测试时具有完全相同的条件。只要您不认为安全是个问题,我就同意使用 md5。
由于您对每个 运行 上不同的元数据非常不明确,我很好奇并做了一个简短的测试。
zip t1 t00*png
zip t2 t00*png
现在一些元变化:
touch t00*.png
zip t3 t00*png
结果:
md5sum *.zip
760a4a1c52f3bc6cdd29c1fff7b94c1f t1.zip
760a4a1c52f3bc6cdd29c1fff7b94c1f t2.zip
83a8dcb9fe0d50e7b2b8012c8842005e t3.zip
这意味着 - 最后我的 zip [1] 版本确实产生了可重复的内容,只要没有更改元数据。
根据定义,您的更改不是文件内容的一部分(例如 JPEG 的 EXIF 数据也是元数据,而是文件的一部分 - 而文件访问日期 不是 )。否则你根本没有机会使用任何散列函数。
因此,如果您想要一个可比较的结果,而文件内容相同但它们的元数据(文件系统的元数据)不同,您只需调整元数据即可节省大量工作。
当你在这里做某种单元测试时,你甚至可以用它来验证 md5-sum 是否相同 调整后的元数据和不同的 没有.
概念验证:
touch t00*.png -d '2000-01-01T0:00'
zip t1 t00*png
touch t00*.png -d
zip t2 t00*png
touch t00*.png -d '2000-01-01T0:00'
zip t3 t00*png
结果:
md5sum *.zip
a1e713c1d91a0042b37043c83bb98d1b t1.zip
3085aa53bee69df4be783636b87ed62c t2.zip
a1e713c1d91a0042b37043c83bb98d1b t3.zip
最后但同样重要的是,您可以尝试调整 ZIP 文件中与您的测试无关的那些区域。由于 ZIP 似乎是一种表现良好的容器格式,因此我更改的元数据以整齐的距离显示 - 强化了我的假设,即每个文件 headers/footers:
cat t1.zip| xxd -ps -c 20 > t1.hd
cat t2.zip| xxd -ps -c 20 > t2.hd
diff t1.hd t2.hd
1c1
< 504b03041400000008000000212822aad7cacc0b
---
> 504b0304140000000800c37a574a22aad7cacc0b
3c3
< 09000370356d3870356d3875780b000104e80300
---
> 0900030df0ae580df0ae5875780b000104e80300
3432c3432
< 6082504b030414000000080000002128143698a4
---
> 6082504b0304140000000800c37a574a143698a4
3434c3434
< 555409000370356d3870356d3875780b000104e8
---
> 55540900030df0ae580df0ae5875780b000104e8
19691,19693c19691,19693
...
请注意元数据更改造成的明显最小差异。
[1] Linux 4.9.9-1-ARCH #1 SMP PREEMPT Thu Feb 9 19:07:09 CET 2017 x86_64 GNU/Linux, <br>
Zip 3.0 (July 5th 2008), by Info-ZIP, Compiled with gcc 5.3.0 for Unix (Linux ELF) on Jan 12 2016.
我需要验证 python 应用程序生成的 zip 文件的内容。我希望每次我们 运行 应用程序时,它都会生成具有相同内容的完全相同的 zip 文件(当提供相同的输入时)。关于内容,我指的只是被压缩文件的内容,而不是这些文件或 zip 文件的元信息。
问题是 zip 文件保留了一些元信息,例如每个文件的创建时间,每次 运行 应用程序时这些信息都不同。不幸的是,这些 zip 文件可能包含数百万个小文件,这使得提取和计算每个小文件的哈希值变得非常不愉快。
做这样的测试有什么好的方法?我一直在尝试 hashlib 中的 "md5" 方法,即将 zip 文件的 md5 值与先前计算的值进行比较。但是,每次 运行 应用程序的 md5 值都不同,因为元信息不同。知道我该怎么做这个测试吗?如果可能的话,我不介意使用相同的元信息来提取和重新压缩它。请注意,zip 文件包含多层目录。
据我了解,您正在尝试编写自动化测试来验证您的 zip 文件的内容是否符合您的预期。
md5 似乎是一个很好的候选者。现在,如果您在 zip 文件中有与时间相关的数据,我建议您为此使用 https://github.com/spulec/freezegun。它被设计为 "suspend" 时间,以便所有对 datetime
函数(now()
、today()
...)的调用都将 return 一个已知值。你可以这样做:
from freezegun import freeze_time
def test_zipping():
with freeze_time("2012-01-14 12:34:56"):
zipfile = create_zip_file(data)
md5 = hashlib.md5()
with open(zipfile_name) , "rb" ) as f:
data = f.read(block_size)
if not data:
break
md5.update(data)
assert md5.digest() == expected_md5_value
有了这个,您应该能够从测试中消除与时间相关的调用的随机性。
(受 Get MD5 hash of big files in Python 启发,因为您的 zip 文件似乎足够大)
我喜欢 Laurent S 的基本想法,以确保您在 运行 测试时具有完全相同的条件。只要您不认为安全是个问题,我就同意使用 md5。
由于您对每个 运行 上不同的元数据非常不明确,我很好奇并做了一个简短的测试。
zip t1 t00*png
zip t2 t00*png
现在一些元变化:
touch t00*.png
zip t3 t00*png
结果:
md5sum *.zip
760a4a1c52f3bc6cdd29c1fff7b94c1f t1.zip
760a4a1c52f3bc6cdd29c1fff7b94c1f t2.zip
83a8dcb9fe0d50e7b2b8012c8842005e t3.zip
这意味着 - 最后我的 zip [1] 版本确实产生了可重复的内容,只要没有更改元数据。
根据定义,您的更改不是文件内容的一部分(例如 JPEG 的 EXIF 数据也是元数据,而是文件的一部分 - 而文件访问日期 不是 )。否则你根本没有机会使用任何散列函数。
因此,如果您想要一个可比较的结果,而文件内容相同但它们的元数据(文件系统的元数据)不同,您只需调整元数据即可节省大量工作。
当你在这里做某种单元测试时,你甚至可以用它来验证 md5-sum 是否相同 调整后的元数据和不同的 没有.
概念验证:
touch t00*.png -d '2000-01-01T0:00'
zip t1 t00*png
touch t00*.png -d
zip t2 t00*png
touch t00*.png -d '2000-01-01T0:00'
zip t3 t00*png
结果:
md5sum *.zip
a1e713c1d91a0042b37043c83bb98d1b t1.zip
3085aa53bee69df4be783636b87ed62c t2.zip
a1e713c1d91a0042b37043c83bb98d1b t3.zip
最后但同样重要的是,您可以尝试调整 ZIP 文件中与您的测试无关的那些区域。由于 ZIP 似乎是一种表现良好的容器格式,因此我更改的元数据以整齐的距离显示 - 强化了我的假设,即每个文件 headers/footers:
cat t1.zip| xxd -ps -c 20 > t1.hd
cat t2.zip| xxd -ps -c 20 > t2.hd
diff t1.hd t2.hd
1c1
< 504b03041400000008000000212822aad7cacc0b
---
> 504b0304140000000800c37a574a22aad7cacc0b
3c3
< 09000370356d3870356d3875780b000104e80300
---
> 0900030df0ae580df0ae5875780b000104e80300
3432c3432
< 6082504b030414000000080000002128143698a4
---
> 6082504b0304140000000800c37a574a143698a4
3434c3434
< 555409000370356d3870356d3875780b000104e8
---
> 55540900030df0ae580df0ae5875780b000104e8
19691,19693c19691,19693
...
请注意元数据更改造成的明显最小差异。
[1] Linux 4.9.9-1-ARCH #1 SMP PREEMPT Thu Feb 9 19:07:09 CET 2017 x86_64 GNU/Linux, <br>
Zip 3.0 (July 5th 2008), by Info-ZIP, Compiled with gcc 5.3.0 for Unix (Linux ELF) on Jan 12 2016.