全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网
对象存储 OSS

通过crc64校验数据传输的完整性

更新时间:2017-10-19 17:34:43

背景

数据在客户端和服务器之间传输时有可能会出错。OSS现在支持对各种方式上传的Object返回其crc64值,客户端可以和本地计算的crc64值做对比,从而完成数据完整性的验证。

  • OSS对新上传的Object进行crc64的计算,并将结果存储为Object的元信息存储,随后在返回的response header中增加x-oss-hash-crc64ecma头部,表示其crc64值,该64位CRC根据 ECMA-182标准 计算得出。
  • 对于crc64上线之前就已经存在于OSS上的Object,OSS不会对其计算crc64值,所以获取此类Object时不会返回其crc64值。

操作说明

  • Put Object / Append Object / Post Object / Multipart upload part 均会返回对应的crc64值,客户端可以在上传完成后拿到服务器返回的crc64值和本地计算的数值进行校验。

  • Multipart Complete时,如果所有的Part都有crc64值,则会返回整个Object的crc64值;否则,比如有crc64上线之前就已经上传的Part,则不返回crc64值。

  • Get Object / Head Object / Get ObjectMeta 都会返回对应的crc64值(如有)。客户端可以在Get Object完成后,拿到服务器返回的crc64值和本地计算的数值进行校验。

    注意:range get请求返回的将会是整个object的crc64值

  • Copy相关的操作,如Copy Object / Upload Part Copy,新生成的Object/Part不保证具有crc64值。

应用示例

以下为完整的Python示例代码,演示如何基于crc64值验证数据传输的完整性。

  1. 计算crc64。

    1. import oss2
    2. from oss2.models import PartInfo
    3. import os
    4. import crcmod
    5. import random
    6. import string
    7. do_crc64 = crcmod.mkCrcFun(0x142F0E1EBA9EA3693L, initCrc=0L, xorOut=0xffffffffffffffffL, rev=True)
    8. def check_crc64(local_crc64, oss_crc64, msg="check crc64"):
    9. if local_crc64 != oss_crc64:
    10. print "{0} check crc64 failed. local:{1}, oss:{2}.".format(msg, local_crc64, oss_crc64)
    11. return False
    12. else:
    13. print "{0} check crc64 ok.".format(msg)
    14. return True
    15. def random_string(length):
    16. return ''.join(random.choice(string.lowercase) for i in range(length))
    17. bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
  2. 验证Put Object。

    1. content = random_string(1024)
    2. key = 'normal-key'
    3. result = bucket.put_object(key, content)
    4. oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
    5. local_crc64 = str(do_crc64(content))
    6. check_crc64(local_crc64, oss_crc64, "put object")
  3. 验证Get Object。

    1. result = bucket.get_object(key)
    2. oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
    3. local_crc64 = str(do_crc64(result.resp.read()))
    4. check_crc64(local_crc64, oss_crc64, "get object")
  4. 验证Upload Part 和 Complete。

    1. part_info_list = []
    2. key = "multipart-key"
    3. result = bucket.init_multipart_upload(key)
    4. upload_id = result.upload_id
    5. part_1 = random_string(1024 * 1024)
    6. result = bucket.upload_part(key, upload_id, 1, part_1)
    7. oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
    8. local_crc64 = str(do_crc64(part_1))
    9. #check 上传的 part 1数据是否完整
    10. check_crc64(local_crc64, oss_crc64, "upload_part object 1")
    11. part_info_list.append(PartInfo(1, result.etag, len(part_1)))
    12. part_2 = random_string(1024 * 1024)
    13. result = bucket.upload_part(key, upload_id, 2, part_2)
    14. oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
    15. local_crc64 = str(do_crc64(part_2))
    16. #check 上传的 part 2数据是否完整
    17. check_crc64(local_crc64, oss_crc64, "upload_part object 2")
    18. part_info_list.append(PartInfo(2, result.etag, len(part_2)))
    19. result = bucket.complete_multipart_upload(key, upload_id, part_info_list)
    20. oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
    21. local_crc64 = str(do_crc64(part_2, do_crc64(part_1)))
    22. #check 最终oss上的object和本地文件是否一致
    23. check_crc64(local_crc64, oss_crc64, "complete object")

OSS SDK支持

部分OSS SDK已经支持上传、下载使用crc64进行数据校验,用法见下表中的示例:

SDK 是否支持CRC 示例
Java SDK CRCSample.java
Python SDK object_check.py
PHP SDK -
C# SDK -
C SDK oss_crc_sample.c
JavaScript SDK -
Go SDK crc_test.go
Ruby SDK -
iOS SDK -
Android SDK - 
本文导读目录