如何重现使用 s3DistCp 复制的 gzip 文件的校验和(从 Google Cloud Storage 到 AWS S3)

How do I reproduce checksum of gzip files copied with s3DistCp (from Google Cloud Storage to AWS S3)

我使用 s3DistCp(如 this AWS article 所述)将大量 gzip 文件从 Google 云存储复制到 AWS 的 S3。当我尝试比较文件的校验和时,它们有所不同(md5/sha-1/sha-256 有同样的问题)。

如果我比较几个文件的大小(字节)或解压缩的内容(diff 或其他校验和),它们匹配。 (在这种情况下,我正在比较通过 gsutil 从 Google 直接拉下来的文件与从 S3 拉下我的 distcp 文件)。

使用file,我确实看到了两者之间的区别:

file1-gs-direct.gz: gzip compressed data, original size modulo 2^32 91571
file1-via-s3.gz:    gzip compressed data, from FAT filesystem (MS-DOS, OS/2, NT), original size modulo 2^32 91571

我的Goal/Question:

我的目标是验证我下载的文件是否与原始文件的校验和匹配,但我不想直接在 Google 上重新下载或分析文件。我可以对我的 s3 存储文件做些什么来重现原始校验和吗?

我尝试过的事情:

用不同的压缩方式重新压缩: 虽然我不希望 s3DistCp 改变原始文件的压缩,但这是我重新压缩的尝试:

target_sha=$(shasum -a 1 file1-gs-direct.gz | awk '{print }')
for i in {1..9}; do
  cur_sha=$(cat file1-via-s3.gz | gunzip | gzip -n -$i | shasum -a 1 | awk '{print }')
  echo "$i. $target_sha == $cur_sha ? $([[ $target_sha == $cur_sha ]] && echo 'Yes' || echo 'No')"
done

1. abcd...1234 == dcba...4321 ? No
2. ... ? No
...
2. ... ? No

在输入我的问题时,我找到了答案:

S3DistCp 显然正在切换 gzip header 中的“OS”版本,这解释了我在 file 中看到的“FAT 文件系统”标签。 (注:为了排除S3直接导致的问题,我把我的“file1-gs-direct.gz”复制到S3上,下拉后校验和还是一样。)

这是两个文件之间的差异:

$ diff <(cat file1-gs-direct.gz | hexdump -C) <(cat file1-via-s3.gz | hexdump -C)
1c1
< 00000000  1f 8b 08 00 00 00 00 00  00 ff ed 7d 59 73 db 4a  |...........}Ys.J|
---
> 00000000  1f 8b 08 00 00 00 00 00  00 00 ed 7d 59 73 db 4a  |...........}Ys.J|

原来 gzip 文件中的第 10 个字节“标识了进行压缩的文件系统的类型”(Gzip RFC):

    +---+---+---+---+---+---+---+---+---+---+
    |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
    +---+---+---+---+---+---+---+---+---+---+

使用 hexedit,我可以将我的“via-s3”文件的 OS 从 00 更改为 FF,然后校验和匹配。

警告: 对稍后解压的文件进行编辑可能会导致意外问题,因此请谨慎使用。 (在我的例子中,我正在做一个文件校验和,所以更糟糕的情况是即使未压缩的内容保持不变,文件也会显示不匹配)。