You need to enable JavaScript to run this app.
文档中心
对象存储

对象存储

复制全文
下载 pdf
校验数据一致性
校验上传对象的一致性
复制全文
下载 pdf
校验上传对象的一致性
您可以使用 Content-MD5、Content-SHA256 或 CRC64 实现上传对象的一致性校验。本文介绍不同方案的校验流程图、示例代码以及各方案的对比信息。​
通过 Content-MD5 校验​
调用 TOS API 上传对象或上传分片时,将客户端计算出的待上传数据的 Content-MD5 值,通过请求头域或表单域传递给 TOS,从而保证上传数据的一致性。​
流程图​
​​​
示例代码​
​
Golang
Java
Python
​
​
package main​
​
import (​
"bytes"​
"context"​
"crypto/md5"​
"encoding/base64"​
​
"github.com/volcengine/ve-tos-golang-sdk/v2/tos"​
)​
​
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)​
}​
​
data := []byte("hello world")​
// 计算 MD5​
hash := md5.New()​
hash.Write(data)​
contentMD5 := base64.StdEncoding.EncodeToString(hash.Sum(nil))​
​
// 指定 Content-MD5 上传对象​
input := &tos.PutObjectV2Input{}​
input.Bucket = bucket​
input.Key = key​
input.Content = bytes.NewReader(data)​
input.ContentMD5 = contentMD5​
_, err = client.PutObjectV2(context.Background(), input)​
if err != nil {​
panic(err)​
}​
}​
​
​
通过 Content-SHA256 校验​
和使用 Content-MD5 校验的方式相同,调用 TOS API 上传对象或上传分片时,将客户端计算出的待上传数据的 Content-SHA256 值,通过请求头域或表单域传递给 TOS,从而保证上传数据的一致性。​
流程图​
​​​
示例代码​
​
Golang
Java
Python
​
​
package main​
​
import (​
"bytes"​
"context"​
"crypto/sha256"​
"encoding/hex"​
​
"github.com/volcengine/ve-tos-golang-sdk/v2/tos"​
)​
​
​
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)​
}​
​
data := []byte("hello world")​
// 计算 SHA256​
hash := sha256.New()​
hash.Write(data)​
contentSHA256 := hex.EncodeToString(hash.Sum(nil))​
​
// 指定 Content-SHA256 上传对象​
input := &tos.PutObjectV2Input{}​
input.Bucket = bucket​
input.Key = key​
input.Content = bytes.NewReader(data)​
input.ContentSHA256 = contentSHA256​
_, err = client.PutObjectV2(context.Background(), input)​
if err != nil {​
panic(err)​
}​
}​
​
​
通过 CRC64 校验​
调用 TOS API 上传对象或上传分片完成后,将客户端计算出的已上传数据的 CRC64,与 TOS 返回的 CRC64 做比较,从而保证单次 API 上传数据的一致性。​
在分片上传场景中,除了验证单次上传的 CRC64 外,在合并分片后,通过组合各个分片的 CRC64 再与服务端返回的整个对象的 CRC64 做比对,进而保证最终 TOS 侧生成对象的数据一致性。​
流程图​
​​​
示例代码​
​
Golang
Python
​
​
package main​
​
import (​
"bytes"​
"context"​
"hash"​
"io"​
​
"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)​
}​
​
resp, err := client.CreateMultipartUploadV2(context.Background(), &tos.CreateMultipartUploadV2Input{​
Bucket: bucket,​
Key: key,​
})​
if err != nil {​
panic(err)​
}​
​
uploadID := resp.UploadID​
parts := make([]tos.UploadedPartV2, 0, 3)​
​
var crc64Final uint64​
data := make([]byte, 1024*1024*5)​
for i := 1; i <= 2; i++ {​
input := &tos.UploadPartV2Input{}​
input.Bucket = bucket​
input.Key = key​
input.UploadID = uploadID​
input.PartNumber = i​
​
crc64Hash := tos.NewCRC(tos.DefaultCrcTable(), 0)​
input.Content = &crc64Reader{​
r: bytes.NewReader(data),​
h: crc64Hash,​
}​
output, err := client.UploadPartV2(context.Background(), input)​
if err != nil {​
panic(err)​
}​
​
crc64Once := crc64Hash.Sum64()​
if output.HashCrc64ecma != crc64Once {​
panic("crc64 not match")​
}​
​
crc64Final = tos.CRC64Combine(crc64Final, crc64Once, uint64(len(data)))​
​
parts = append(parts, tos.UploadedPartV2{​
PartNumber: input.PartNumber,​
ETag: output.ETag,​
})​
}​
​
output, err := client.CompleteMultipartUploadV2(context.Background(), &tos.CompleteMultipartUploadV2Input{​
Bucket: bucket,​
Key: key,​
UploadID: uploadID,​
Parts: parts,​
})​
​
if err != nil {​
panic(err)​
}​
​
if output.HashCrc64ecma != crc64Final {​
panic("crc64 not match")​
}​
}​
​
​
方案对比​
​
校验方式​
通过Content-MD5​
通过Content-SHA256​
通过CRC64​
适用场景​
  • 事先知道待上传数据的 MD5 。​
  • 待上传数据较小,例如数据大小在10 MB以内,否则事先计算的成本较高。​
  • 数据校验不成功,不希望 TOS 侧生成对象的场景。​
  • 事先知道待上传数据的 SHA256。​
  • 待上传数据较小,例如数据大小在10 MB以内,否则事先计算的成本较高。​
  • 数据校验不成功,不希望 TOS 侧生成对象的场景。​
  • 希望使用更安全的哈希算法用于数据校验。​
  • CRC64 可以在上传数据的过程中同步计算,没有额外计算一次的开销。​
  • 对于分片上传的场景,可以对比计算合并后最终对象的 CRC64,校验结果更可靠。​
缺点​
  • 需要事先计算出待上传数据的 MD5,有一定的成本。​
  • MD5算法的安全性低于 SHA256 算法。​
  • 需要事先计算出待上传数据的 SHA256,有一定的成本。​
  • SHA256 算法的效率低于 MD5 算法。​
校验过程在客户端完成,此时 TOS 侧已生成实际上传的对象,需要额外的做覆盖或删除等清理工作。​
支持的 API​
  • PutObject​
  • UploadPart​
  • PutObject​
  • PostObject​
  • UploadPart​
推荐说明​
  • 如果不希望有额外的计算开销,优先选择 CRC64 校验的方案。​
  • 如果希望数据不一致时不在 TOS 侧生成对象,且希望使用更安全的哈希算法时,推荐使用 Content-SHA256 校验的方案;否则可以使用 Content-MD5 校验的方案。​
​
​
​
​
​
最近更新时间:2026.10.10 16:36:50
这个页面对您有帮助吗?
有用
有用
无用
无用