在S3存储桶中,常用ETag来标记文件或者比较文件是否相同。在某些情况下ETag和我们用的MD5码是相同的,但在分块上传的文件中ETag和MD5码是不一样的。

ETag类似:

d41d8cd98f00b204e9800998ecf8427e-2

前面部分d41d8cd98f00b204e9800998ecf8427e(即-号前)是ETag计算的一个标识(此处我们先定义为ETag码);后面部分2表示文件是分了两个Part上传的。

参考网上大神的解释,这一部分可以表示为如下形式:

hexmd5( md5( part1 ) + md5( part2 ) )-{ number of parts }

看到上面公式,大家应该了解到ETag码的生成方式了,如果对于多个Part可以形如更通用的形式:

hexmd5( md5( part1 ) + md5( part2 ) + ... + md5( partn ) )-{ n }

如果我们需要比较本地文件和S3存储文件是否抑制我们可以根据上面的方式计算本地文件的ETag码和云端进行比对,此处我给大家一个简单的实例,供大家参考:


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import hashlib
from hashlib import md5


def calc_etag(inputfile, partsize=8388608):
    md5_digests = []
    with open(inputfile, 'rb') as f:
        for chunk in iter(lambda: f.read(partsize), b''):
            md5_digests.append(md5(chunk).digest())
    return md5(b''.join(md5_digests)).hexdigest() + '-' + str(len(md5_digests))


if __name__ == "__main__":
    # 块的大小8388608是boto3.s3.transfer.TransferConfig中默认上传的分块大小
    print(calc_etag("demo.zip"))

如此我们在云端同步时能同时校验本地文件的完整性。

参考资料:

1.https://teppen.io/2018/06/23/aws_s3_etags/