全部產品
Search
文件中心

Object Storage Service:通過crc64校正資料轉送的完整性

更新時間:Feb 28, 2024

資料在用戶端和伺服器之間傳輸時有可能會出錯。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值。

操作說明

  • PutObject、AppendObject、PostObject、MultipartUploadPart均會返回對應的crc64值,用戶端可以在上傳完成後拿到伺服器返回的crc64值和本地計算的數值進行校正。

  • MultipartComplete時,如果所有的Part都有crc64值,則會返回整個Object的crc64值;若某些Part沒有crc64值,則不返回整個Object的crc64值。例如某個Part在crc64上線之前就已經上傳,則不返回crc64值。

  • GetObject、HeadObject、GetObjectMeta都會返回對應的crc64值(如有)。用戶端可以在GetObject完成後,拿到伺服器返回的crc64值和本地計算的數值進行校正。

    說明

    range get請求返回的將會是整個Object的crc64值。

  • Copy相關的操作,如CopyObject、UploadPartCopy,新產生的Object/Part不保證具有crc64值。

應用樣本

以下為完整的Python範例程式碼,示範如何基於crc64值驗證資料轉送的完整性。

import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
import crcmod
import random
import string
from oss2.models import PartInfo

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# yourBucketName填寫儲存空間名稱。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName')
# 建立CRC64校正函數。
do_crc64 = crcmod.mkCrcFun(0x142F0E1EBA9EA3693, initCrc=0, xorOut=0xffffffffffffffff, rev=True)

# 校正CRC64和列印結果。
def check_crc64(local_crc64, oss_crc64, msg="check crc64"):
    if local_crc64 != oss_crc64:
        print("{0} check crc64 failed. local:{1}, oss:{2}.".format(msg, local_crc64, oss_crc64))
        return False
    else:
        print("{0} check crc64 ok.".format(msg))
        return True

# 產生指定長度的隨機字串。
def random_string(length):
    return ''.join(random.choice(string.ascii_lowercase) for i in range(length))

# 產生一個長度為1024的隨機字串content。
content = random_string(1024)

# 設定檔案的路徑。
key = 'normal-key'

# 驗證PutObject。
result = bucket.put_object(key, content)
oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
local_crc64 = str(do_crc64(oss2.to_bytes(content)))
check_crc64(local_crc64, oss_crc64, "put object")

# 驗證PutObject。
result = bucket.get_object(key)
oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
local_crc64 = str(do_crc64(result.resp.read()))
check_crc64(local_crc64, oss_crc64, "get object")

# 驗證UploadPart和Complete。
part_info_list = []
key = "multipart-key"
result = bucket.init_multipart_upload(key)
upload_id = result.upload_id
part_1 = random_string(1024 * 1024)
result = bucket.upload_part(key, upload_id, 1, part_1)
oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
local_crc64 = str(do_crc64(oss2.to_bytes(part_1)))
# 檢查上傳的part 1資料是否完整。
check_crc64(local_crc64, oss_crc64, "upload_part object 1")
part_info_list.append(PartInfo(1, result.etag, len(part_1)))
part_2 = random_string(1024 * 1024)
result = bucket.upload_part(key, upload_id, 2, part_2)
oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
local_crc64 = str(do_crc64(oss2.to_bytes(part_2)))
# 檢查上傳的part 2資料是否完整。
check_crc64(local_crc64, oss_crc64, "upload_part object 2")
part_info_list.append(PartInfo(2, result.etag, len(part_2)))
result = bucket.complete_multipart_upload(key, upload_id, part_info_list)
oss_crc64 = result.headers.get('x-oss-hash-crc64ecma', '')
local_crc64 = str(do_crc64(oss2.to_bytes(part_2), do_crc64(oss2.to_bytes(part_1))))
# 檢查最終oss上的object和本地檔案是否一致。
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

OSSCrc64Tests.m

Android SDK

CRC64Test.java