Swift、Amazon S3、eTag 和大于 5MB 的文件的 MD5 哈希

Swift, Amazon S3, eTag and MD5 hash for files > 5MB

在我的应用程序中,我将视频从 Amazon S3 云下载到沙箱。为了确保下载的文件没有损坏,我将对象的 eTag(由亚马逊提供)与驻留在本地文件系统中的下载对象的 MD5 哈希进行比较。对于小视频(< 5MB)我的算法工作正常 - eTag 和 MD5 哈希是相同的。

对于更大的文件,两个参数不再匹配 - 据我所知,亚马逊为大于 5MB 的文件生成不同的 eTag - eTag 也有一个尾随连字符和后面的数字(也许是块的数量? ):

8c18c4ed68bc9db377cb2d3225c0ee31-4

在 Internet 上,我找不到为更大的文件计算正确的 MD5 哈希值的解决方案或代码片段。

计算 MD5 哈希,我都试过了

localData.md5().toHexString() // CryptoSwift

两者

var md5: String? {

   let hash = localData.withUnsafeBytes { (bytes: UnsafePointer<Data>) -> [UInt8] in
   var hash: [UInt8] = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
   CC_MD5(bytes, CC_LONG(localData.count), &hash)
       return hash
   }
   return hash.map { String(format: "%02x", [=12=]) }.joined()
}

有人知道如何解决这个问题吗? 也许我应该专注于另一种方法 - 例如检查下载的视频是否可以打开?

我认为更可行的策略是在结构化响应中存储预先计算的哈希值(您很可能有一个 JSON、XML、<insert your favourite wire format here> 引用S3 URL,不是吗?)。

  {
    "url": "https://.../myfile.mpeg",
    "sha256": "9e7bf344f14a1fd2f98abbd736fa3c777ef6088e9b964858bbb524e88322a938"
  }

依赖于 S3 的 ETag 生成算法将在他们决定更改实现时随时中断。此外,CDN 通常无法很好地处理 ETag,并且 ETag 往往因镜像而异(在一家推出私有 CDN 的公司工作过就是这种情况)。因此,如果您决定放弃 S3,您的逻辑也可能会崩溃。