本文介绍通过CRC64校验下载对象一致性的方案及示例代码。
在单次下载整个对象的场景中,调用TOS API接口下载对象完成后,将客户端计算出的已下载数据的CRC64与TOS返回的CRC64比较,从而保证下载数据的一致性。
在Range下载场景,通过Range分片方式下载完整个对象后,组合各个Range分片的CRC64再与服务端返回的整个对象的CRC64做比对,进而保证最终下载对象的数据一致性。关于CRC64参数的说明,请参见相关概念。
说明
上传对象的一致性校验方案,请参见校验上传对象的一致性。
package main import ( "context" "hash" "io" "io/ioutil" "github.com/volcengine/ve-tos-golang-sdk/v2/tos" ) type crc64Reader struct { r io.Reader h hash.Hash64 } func (cr *crc64Reader) Read(p []byte) (n int, err error) { n, err = cr.r.Read(p) cr.h.Write(p[:n]) return n, err } func main() { var ( accessKey = "your access key" secretKey = "your secret key" endpoint = "your endpoint" region = "your region" bucket = "bucketname" key = "objectname" ) client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey))) if err != nil { panic(err) } output, err := client.GetObjectV2(context.Background(), &tos.GetObjectV2Input{ Bucket: bucket, Key: key, }) defer output.Content.Close() p := make([]byte, 1024) crc64Hash := tos.NewCRC(tos.DefaultCrcTable(), 0) reader := &crc64Reader{ r: output.Content, h: crc64Hash, } for { _, err = reader.Read(p) if err != nil { if err == io.EOF{ break } panic(err) } } if output.HashCrc64ecma != crc64Hash.Sum64() { panic("crc64 not match") } }
import tos endpoint = 'your endpoint' access_key = 'your access key' secret_key = 'your secret key' region = 'your region' bucket = 'bucketname' key = 'objectname' crc64 = tos.utils.Crc64() client = tos.TosClientV2(access_key, secret_key, endpoint, region) try: resp = client.get_object(bucket, key) print(resp.status_code) while True: chunk = resp.content.read(65536) if not chunk: break crc64.update(chunk) if resp.hash_crc64_ecma != crc64.crc: raise Exception('crc64 not match') except Exception as e: print(e)