CRC64校验

2026-02-09   访问量:1005


简介

数据在客户端和服务器间传输时可能会出现错误,COS 除了可以通过 MD5和自定义属性 验证数据完整性外,还可以通过 CRC64检验码来进行数据校验。

COS 会对新上传的对象进行 CRC64计算,并将结果作为对象的属性进行存储,随后在返回的响应头部中携带 x-cos-hash-crc64ecma,该头部表示上传对象的 CRC64值,根据 ECMA-182标准 计算得到。对于 CRC64特性上线前就已经存在于 COS 的对象,COS 不会对其计算 CRC64值,所以获取此类对象时不会返回其 CRC64值。

说明:

CRC64(循环冗余校验64位)是一种高效的数据完整性验证算法,通过多项式除法生成64位校验值。相比传统 MD5校验,CRC64具备以下优势:

抗碰撞性更强:64位校验码空间更大,重复概率低。

计算效率更高:流式处理特性适合大文件校验,内存占用仅为常数级别。

支持片段合并:适合异步边下载边计算,节省计算时间。

行业认可度高:被 ISO、ITU-T 等国际标准广泛采用,腾讯云 COS 选用 ECMA-182标准实现。

COS API 支持 CRC64校验

目前支持 CRC64的 API 如下:

简单上传接口

PUT ObjectPOST Object:用户可在返回的响应头中获得文件 CRC64校验值。

分块上传接口

Upload Part:用户可以根据 COS 返回的 CRC64值与本地计算的数值进行比较验证。

Complete Multipart Upload:如果每个分块都有 CRC64属性,则会返回整个对象的 CRC64值,如果某些分块不具备 CRC64值,则不返回。

执行 Upload Part - Copy 时,会返回对应的 CRC64值。

执行 PUT Object - Copy 时,如果源对象存在 CRC64值,则返回 CRC64,否则不返回。

执行 HEAD ObjectGET Object 时,如果对象存在 CRC64,则返回。用户可以根据 COS 返回的 CRC64值和本地计算的 CRC64进行比较验证。

查看 COS 对象 CRC64值

方式一:通过 COSBrowser PC/Web 查看

安装 并登录 COSBrowser PC 客户端或访问 COSbrowser Web 版本,进入存储桶后,选择对象并右键单击详情。在对象详情中,Headers 对应的 x-cos-hash-crc64ecma 头部值就是 CRC64校验值。




方式二:通过浏览器查看

在浏览器打开 DevTools 开发者工具,访问对象临时签名地址,然后在 Network 里可以看到对象的 Response Headers,对应的 x-cos-hash-crc64ecma 头部值就是当前访问对象的 CRC64校验值。




计算本地文件 CRC64值

方式一:使用 COSCLI 工具计算 CRC64值

COSCLI 是腾讯云对象存储提供的客户端命令行工具。通过 COSCLI 工具,您可以通过简单的命令行指令对您 COS 中的对象(Object)实现 CRC64计算以及批量上传、下载、删除等操作。

下载工具后,可以使用./coscli hash ./filename 命令计算得到本地文件 CRC64校验值。Window、Linux 示例如下:




方式二:使用 Web 页面计算 CRC64值

浏览器访问 在线计算 CRC64 页面,单击选择文件,完成上传后,当前页面会在计算完成后自动显示校验值。




API 接口示例

分块上传响应

下面为用户发出 Upload Part 请求后得到的响应示例。x-cos-hash-crc64ecma 头部表示分块的 CRC64值,用户可以通过该值与本地计算的 CRC64值进行比较,从而校验分块完整性。

HTTP/1.1 200 OKcontent-length: 0connection: closedate: Thu, 05 Dec 2019 01:58:03 GMTetag: "358e8c8b1bfa35ee3bd44cb3d2cc416b"server: tencent-cosx-cos-hash-crc64ecma: 15060521397700495958x-cos-request-id: NWRlODY0MmJfMjBiNDU4NjRfNjkyZl80ZjZi****

完成分块上传响应

下面为用户发出 Complete Multipart Upload 请求后得到的响应示例。x-cos-hash-crc64ecma 头部表示整个对象的 CRC64值,用户可以通过该值与本地计算的 CRC64值进行比较,从而校验对象完整性。

HTTP/1.1 200 OK

content-type: application/xml

transfer-encoding: chunked

connection: close

date: Thu, 05 Dec 2019 02:01:17 GMT

server: tencent-cos

x-cos-hash-crc64ecma: 15060521397700495958

x-cos-request-id: NWRlODY0ZWRfMjNiMjU4NjRfOGQ4Ml81MDEw****



[Object Content]

SDK 使用示例

Python SDK

下面以 Python SDK 为例演示如何校验对象,完整的示例代码如下。

说明:

代码基于 Python 2.7,其中 Python SDK 详细使用方式,请参见 Python SDK 的 对象操作 文档。

1. 初始化配置

设置用户属性,包括 SecretId、SecretKey 和 Region,并创建客户端对象。

# -*- coding=utf-8

from qcloud_cos import CosConfig

from qcloud_cos import CosS3Client

from qcloud_cos import CosServiceError

from qcloud_cos import CosClientError

import sys

import os

import logging

import hashlib

import crcmod



logging.basicConfig(level=logging.INFO, stream=sys.stdout)



# 设置用户属性, 包括 SecretId, SecretKey, Region

# APPID 已在配置中移除,请在参数 Bucket 中带上 APPID。Bucket 由 BucketName-APPID 组成

secret_id = os.environ['COS_SECRET_ID']     # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140

secret_key = os.environ['COS_SECRET_KEY']   # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140

region = 'ap-beijing'      # 替换为您的 Region, 这里以北京为例

token = None               # 使用临时密钥需要传入 Token,默认为空,可不填

config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token)  # 获取配置对象

client = CosS3Client(config)

2. 计算对象的校验值

模拟对象分块,并计算整个对象的 CRC64校验值。

OBJECT_PART_SIZE = 1024 * 1024      #模拟每个分块的大小

OBJECT_TOTAL_SIZE = OBJECT_PART_SIZE * 1 + 123      #对象的总大小

object_body = '1' * OBJECT_TOTAL_SIZE       #对象内容



#计算整个对象 CRC64校验值

c64 = crcmod.mkCrcFun(0x142F0E1EBA9EA3693, initCrc=0, xorOut=0xffffffffffffffff, rev=True)

local_crc64 =str(c64(object_body.encode()))

3. 初始化分块上传

#初始化分块上传response = client.create_multipart_upload(    Bucket='examplebucket-1250000000',  #替换为您的 Bucket 名称,examplebucket 是一个举例的存储桶,1250000000 为举例的 APPID    Key='exampleobject',                #替换为您上传的对象 Key 值    StorageClass='STANDARD',            #对象的存储类型)#获取分块上传的 UploadIdupload_id = response['UploadId']

4. 分块上传对象

分块上传对象,通过将对象切分成多个块进行上传,最多支持10000分块,每个分块大小为1MB - 5GB,最后一个分块可以小于1MB。上传分块时,需要设置每个分块的 PartNumber(编号),并计算每个分块的 CRC64值,在分块上传成功后,可以通过返回的 CRC64值与本地计算的数值进行校验。

#分块上传对象,每个分块大小为 OBJECT_PART_SIZE ,最后一个分块可能不足 OBJECT_PART_SIZE

part_list = list()

position = 0

left_size = OBJECT_TOTAL_SIZE

part_number = 0

while left_size > 0:

   part_number += 1

   if left_size >= OBJECT_PART_SIZE:

       body = object_body[position:position+OBJECT_PART_SIZE]

   else:

       body = object_body[position:]

   position += OBJECT_PART_SIZE

   left_size -= OBJECT_PART_SIZE

   local_part_crc64 = str(c64(body)) #本地计算 CRC64



   response = client.upload_part(

       Bucket='examplebucket-1250000000',

       Key='exampleobject',

       Body=body,

       PartNumber=part_number,

       UploadId=upload_id,

   )  

   part_crc_64 = response['x-cos-hash-crc64ecma'] # 服务器返回的 CRC64

   if local_part_crc64 != part_crc_64: # 数据检验

       print 'crc64 check FAIL'

       # print('crc64 check FAIL') # Python 3.x 版本的 print 语句

       exit(-1)

   etag = response['ETag']

   part_list.append({'ETag' : etag, 'PartNumber' : part_number})

5. 完成分块上传

在所有分块上传完成后,需要进行完成分块上传操作。可以通过 COS 返回的 CRC64和本地对象的 CRC64进行比较验证。

#完成分块上传response = client.complete_multipart_upload(    Bucket='examplebucket-1250000000',  #替换为您的 Bucket 名称,examplebucket 是一个举例的存储桶,1250000000 为举例的 APPID    Key='exampleobject',             #对象的 Key 值    UploadId=upload_id,    MultipartUpload={       #要求每个分块的 ETag 和 PartNumber 一一对应        'Part' : part_list        },)crc64ecma = response['x-cos-hash-crc64ecma']if crc64ecma != local_crc64: # 数据检验    print 'check crc64 Failed'    # print('crc64 check FAIL') # Python 3.x 版本的 print 语句    exit(-1)

Java SDK

上传对象,推荐使用 Java SDK 的高级接口,参见 Java SDK 对象操作

如何在本地计算文件的 CRC64值

String calculateCrc64(File localFile) throws IOException {

   CRC64 crc64 = new CRC64();



   try (FileInputStream stream = new FileInputStream(localFile)) {

       byte[] b = new byte[1024 * 1024];

       while (true) {

           final int read = stream.read(b);

           if (read <= 0) {

               break;

           }

           crc64.update(b, read);

       }

   }



   return Long.toUnsignedString(crc64.getValue());

}

如何获得 COS 对象的 CRC64值,并与本地文件做校验

// COSClient 的创建参考:[快速入门](https://cloud.tencent.com/document/product/436/10199);

ObjectMetadata cosMeta = COSClient().getObjectMetadata(bucketName, cosFilePath);

String cosCrc64 = cosMeta.getCrc64Ecma();

String localCrc64 = calculateCrc64(localFile);



if (cosCrc64.equals(localCrc64)) {

   System.out.println("ok");

} else {

   System.out.println("fail");

}

iOS SDK

上传对象,推荐使用高级接口上传,参见 iOS SDK 高级上传

如何计算本地文件的 CRC64值

Objective-C 示例:
int64_t localCrc64 = [[[NSMutableData alloc] initWithContentsOfFile:@"本地文件路径"] qcloud_crc64];NSString *localCrc64Str = [NSString stringWithFormat:@"%llu",localCrc64];
Swift 示例:
let localCrc64 = NSMutableData.init(contentsOfFile: "本地文件路径")?.qcloud_crc64();let localCrc64Str = String(format: "%llu", localCrc64 ?? 0);

如何获得 COS 对象的 CRC64值, 并与本地文件做校验

Objective-C 示例:
// 上传完成的回调中,进行获取上传文件的 CRC64值[request setFinishBlock:^(QCloudUploadObjectResult *result, NSError *error) {    NSDictionary * dic = [result __originHTTPURLResponse__].allHeaderFields;    NSString * crc64 = dic[@"x-cos-hash-crc64ecma"];}];
Swift 示例:
// 上传完成的回调中,进行获取上传文件的 CRC64值uploadRequest.setFinish { (result, error) in    let dic = result?.__originHTTPURLResponse__.allHeaderFields;    let crc64 = dic?["x-cos-hash-crc64ecma"];}

下载接口校验

腾讯云 COS iOS SDK 下载接口已经支持 CRC64校验,并默认开启,用户无需手动计算。

校验过程为异步分段校验,减少大文件 CRC64校验造成的耗时。

校验失败后会重试三次,重试后还是失败则会下载失败并在失败回调中给出 CRC64校验失败的异常。

续传时会先校验本地已下载的文件是否符合 CRC64校验结果,如果不一致则重新下载,以免全部下载完才发现不一致,造成用户时间、流量的浪费。

Android SDK

您在上传或者下载成功后,可以在响应头部中获取 CRC64值。

注意:

COS Android SDK 版本需要大于等于 v5.7.5。

上传请求示例

// 1. 初始化 TransferService。在相同配置的情况下,您应该复用同一个 TransferService

TransferConfig transferConfig = new TransferConfig.Builder()

       .build();

TransferService transferService = new TransferService(cosXmlService, transferConfig);



// 2. 初始化 PutObjectRequest

// 存储桶名称,由 bucketname-appid 组成,appid 必须填入,可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket

String bucket = "examplebucket-1250000000";

String cosPath = "exampleobject"; //对象在存储桶中的位置标识符,即称对象键

String srcPath = "examplefilepath"; //本地文件的绝对路径

PutObjectRequest putObjectRequest = new PutObjectRequest(bucket,

       cosPath, srcPath);



// 3. 调用 upload 方法上传文件

final COSUploadTask uploadTask = transferService.upload(putObjectRequest);

uploadTask.setCosXmlResultListener(new CosXmlResultListener() {

   @Override

   public void onSuccess(CosXmlRequest request, CosXmlResult result) {

       // 上传成功,可以在这里拿到文件的 CRC64

       String crc64 = result.getHeader("x-cos-hash-crc64ecma");

   }



   // 如果您使用 kotlin 语言来调用,请注意回调方法中的异常是可空的,否则不会回调 onFail 方法,即:

   // clientException 的类型为 CosXmlClientException?,serviceException 的类型为 CosXmlServiceException?

   @Override

   public void onFail(CosXmlRequest request,

                      @Nullable CosXmlClientException clientException,

                      @Nullable CosXmlServiceException serviceException) {

       if (clientException != null) {

           clientException.printStackTrace();

       } else {

           serviceException.printStackTrace();

       }

   }

});

说明:

更多完整示例,请前往 GitHub 查看。

下载请求示例

腾讯云 COS Android SDK 下载接口已经支持 CRC64校验,并默认开启,用户无需手动计算。

校验过程为异步分段校验,减少大文件 CRC64校验造成的耗时。

校验失败后会重试三次,重试后还是失败则会下载失败并在失败回调中给出 CRC64校验失败的异常。

续传时会先校验本地已下载的文件是否符合 CRC64校验结果,如果不一致则重新下载,以免全部下载完才发现不一致,造成用户时间、流量的浪费。

// 1. 初始化 TransferService。在相同配置的情况下,您应该复用同一个 TransferService

TransferConfig transferConfig = new TransferConfig.Builder()

       .build();

TransferService transferService = new TransferService(cosXmlService, transferConfig);



// 2. 初始化 GetObjectRequest

// 存储桶名称,由bucketname-appid 组成,appid必须填入,可以在COS控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket

String bucket = "examplebucket-1250000000";

String cosPath = "exampleobject"; //对象在存储桶中的位置标识符,即称对象键

String savePathDir = context.getCacheDir().toString(); //本地目录路径

//本地保存的文件名,若不填(null),则与 COS 上的文件名一样

String savedFileName = "exampleobject";

GetObjectRequest getObjectRequest = new GetObjectRequest(bucket,

       cosPath, savePathDir, savedFileName);



// 3. 调用 download 方法下载文件

final COSDownloadTask downloadTask = transferService.download(getObjectRequest);

downloadTask.setCosXmlResultListener(new CosXmlResultListener() {

   @Override

   public void onSuccess(CosXmlRequest request, CosXmlResult result) {

       // 下载成功,可以在这里拿到 COS 上的文件 CRC64

       String cosCRC64 = result.getHeader("x-cos-hash-crc64ecma");

   }



   // 如果您使用 kotlin 语言来调用,请注意回调方法中的异常是可空的,否则不会回调 onFail 方法,即:

   // clientException 的类型为 CosXmlClientException?,serviceException 的类型为 CosXmlServiceException?

   @Override

   public void onFail(CosXmlRequest request,

                      @Nullable CosXmlClientException clientException,

                      @Nullable CosXmlServiceException serviceException) {

       if (clientException != null) {

           clientException.printStackTrace();

       } else {

           serviceException.printStackTrace();

       }

   }

});

说明:

更多完整示例,请前往 GitHub 查看。

CRC64校验

通过 TransferService 进行上传和下载时,SDK 默认进行了数据校验的工作,如果您仍然希望能够自己进行 CRC64校验,可以参考如下代码。

// 1. 参考以上上传或者下载请求示例代码获取 COS 对象的 CRC64值

String cosCRC64 = "examplecoscrc64";



// 2. 计算本地文件的 CRC64

File localFile = new File("examplefilepath");

String localCRC64 = DigestUtils.getCRC64String(localFile);



// 3. 比对 localCRC64 和 cos CRC64 是否一致

if (localCRC64.equals(cosCRC64)) {

   // CRC64 对比正确

}

说明:

更多完整示例,请前往 GitHub 查看。

CRC64各语言示例代码

若需要自定义 CRC64校验,我们也提供了主流语言(Node.js、Java、Go、PHP、C++、C、.NET(C#)、Android、iOS 等)的 CRC64校验示例代码。

使用示例:

Node.Js

Java

Go

Php

C++

C

.NET(C#)

Android

iOS

// 1. CRC64计算 字符串、Buffer 

// 结果:11051210869376104954

crc64('123456789')



// 2. 流式计算

// 结果:11051210869376104954

const hash21 = crc64Calculator().update('123').update('456').update('789').digest();



// 3. 追加计算

// 结果:11051210869376104954

const hash3 = crc64Concat(crc64('123456'), crc64('789'), 3);



// 4. 合并计算

// // 结果:11051210869376104954

const hash4 = crc64Combine([    {hash: crc64('12'), size: 2},    {hash: crc64('345'), size: 3},    {hash: crc64('6789'), size: 4},]);

// 5. 计算文件

crc64File('your_file_path', (err, hash5) => {    console.log('5.', hash5);});

说明:

完整代码下载地址如下:

Github 地址:单击下载

快速下载地址:单击下载


热门文章
更多>