我使用 Python 的 PyDrive2 包下载了 Google Drive 的所有内容,并对本地驱动器中的文件和 Google Drive 上的内容进行了比较,发现其中一些文件的 md5 哈希值不同。本地驱动器上的所有文件均未发生过更改,但…

从我的本地驱动器…

    "Pay Stubs/Wendy's/01-11-2022.pdf": {
        "size": 3872,
        "checksum": "1891f224f046ef7ff05b9dc69e275155"
    },

来自 Google Drive…

    "Pay Stubs/Wendy's/01-11-2022.pdf": {
        "size": 3872,
        "checksum": "60e94f02230b42d5288878550f01f315"
    },

我已经使用 fsspec 下载了文件的字节内容,并在本地生成了 md5 哈希,并且该哈希就是它应该的样子。

            # GoogleDrive inherits pydrive2.fs.GDriveFileSystem https://docs.iterative.ai/PyDrive2/fsspec/
            # pydrive2.fs.GDriveFileSystem inherits fsspec.AbstractFileSystem
            # https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem
            Drive = GoogleDrive()
            print(Drive.info(path = 'root/Pay Stubs/Wendy\'s/01-11-2022.pdf'))

            with Drive.open(path = 'root/Pay Stubs/Wendy\'s/01-11-2022.pdf', mode = 'rb') as rfile:
                print(hashlib.md5(string = rfile.read(), usedforsecurity = True).hexdigest())
{'name': "root/Pay Stubs/Wendy's/01-11-2022.pdf", 'type': 'file', 'size': 3872, 'checksum': '60e94f02230b42d5288878550f01f315'}
60e94f02230b42d5288878550f01f315

无论如何,我的问题是,下载文件后,Windows 可能会对文件的字节内容进行哪些更改,从而导致最终得到不同的 MD5 哈希值?

4

  • 1
    任何东西都可能被改变,因为在密码学中,即使短语中的微小变化也会导致非常不同的哈希值,就像“Pass”和“pass”会产生非常独特的结果一样。


    – 

  • 1
    如果我想确切地知道哪些字节不同,我会为两个文件创建一个十六进制转储(最好包含两种表示形式、十六进制代码和 ASCII 字符),然后使用之类的 diff 工具进行比较。如果我不得不猜测,我会说你会在某种时间戳中找到差异。


    – 

  • 那么 PyDrive2 的清白已经被证明了吗?


    – 

  • 是的,pydrive2 没有这个问题。我下载文件后,会进行本地 MD5 哈希计算。


    – 


最佳答案
1

很难确定根本原因,但有几种可能性:

  • 替代数据流 (ADS):Windows 允许文件具有与其关联的其他数据流,例如跟踪文件的来源。这通常是用户在下载文件时无法看到的内容。

  • 防病毒软件:在文件扫描期间,您的防病毒软件可能会对文件进行修改。

(第一种和第二种情况都是元数据潜入文件的症状)

  • 文件损坏:可能不太可能的情况是,当您下载文件时文件已损坏,并且文件或存储设备的某处已损坏。

说实话,如果您对这些设备非常好奇,您可以从技术上对这两个文件进行逐字节的比较,但我并不确定如何使用 Google Drive 来做到这一点。

5

  • 使用 pydrive2.fs (fsspec),我可以“打开”并下载文件中的字节,而不是文件本身。


    – 

  • 5
    替代数据流与原始文件数据无关,原始文件数据才是要进行哈希处理的内容。我几乎可以保证添加了一个替代数据流(Windows 上的大多数东西都会在Zone.IdentifierADS 中用其原点标记“远程”文件),但这对于读取文件内容的任何东西来说都是完全不可见的(就像 Linux/BSD/BeOS/Solaris/AIX 上的 xattrs 或 macOS 上的命名分支一样),因此它对哈希应该没有任何影响。


    – 

  • @phpjunkie 字节就是文件本身。


    – 

  • @alkanen 是的,我说的是下载文件的字节内容,而不是文件本身。单击要下载的文件时,实际上是在下载文件,要使用 md5 对文件进行哈希处理,如果文件是二进制文件,则必须打开它并对文件的字节内容进行哈希处理。对于文本文件,您必须对文件中的字符串内容进行编码,然后才能使用 md5 对文件内容进行哈希处理。


    – 


  • @phpjunkie 文本文件的工作方式并非如此… 恰恰相反。所有文件的内容都是同一种“二进制”——即字符串内容在写入文件时进行编码,在加载时(可选)进行解码,而不是相反。


    –