在 oss php sdk进行crc64校验

    xiaoxiao2026-02-28  8

    背景

    使用oss php sdk上传下载文件时为了确保数据的一致性,可以使用crc64校验,与使用md5相比,crc64可以便上传/下载边校验。oss是同时支持这两种校验的总所周知,php计算能力弱的特征,本文章还提供一种在php中嵌入c代码实现crc64校验算法,以大幅提升上传下载性能

    使用php实现crc64检验算法

    <?php /** * @return array */ function crc64Table() { $crc64tab = []; // ECMA polynomial $poly64rev = (0xC96C5795 << 32) | 0xD7870F42; //printf("poly:%x\n", $poly64rev); // ISO polynomial // $poly64rev = (0xD8 << 56); for ($n = 0; $n < 256; $n++) { $crc = $n; for ($k = 0; $k < 8; $k++) { if ($crc & 1 === 1 ) { $crc = ($crc >> 1) & ~(0x8 << 60) ^ $poly64rev; } else { $crc = ($crc >> 1) & ~(0x8 << 60); } } $crc64tab[$n] = $crc; } return $crc64tab; } /** * @param string $string * @param string $format * @return mixed * Formats: * crc64('php'); // afe4e823e7cef190 * crc64('php', '0x%x'); // 0xafe4e823e7cef190 * crc64('php', '0x%X'); // 0xAFE4E823E7CEF190 * crc64('php', '%d'); // -5772233581471534704 signed int * crc64('php', '%u'); // 12674510492238016912 unsigned int */ function crc64 ($crc, $string) { static $crc64tab; if ($crc64tab === null) { $crc64tab = crc64Table(); } for ($i = 0; $i < strlen($string); $i++) { $crc = ~$crc; $crc = $crc64tab[($crc ^ ord($string[$i])) & 0xff] ^ (($crc >> 8) & ~(0xff << 56)); $crc = ~$crc; } return $crc; } printf("%u\n", crc64(1, "12345678")); ?>

    function crc64 ($crc, $string)支持边上传边校验, 但由于php是在不擅长做计算密集型的工作(如果这个也算的话),加上校验会拖慢上传/下载将近10倍,没有实际应用的价值。可以选用c实现算法在嵌入php中运行。

    php嵌入c语言的方法

    方法概述:用c语言实现crc64校验算法生成一个.so的动态库放到php可以调用的路径

    用C开发PHP扩展的时候如果用动态链接库的方式编译扩展模块,需要用到phpize. phpize -v 一下查看下有没有安装。没有安装phpize的话, ubutun下apt-get install php5-dev根据自己的php版本下载php源码(可以用php -v查看php版本), 例如你的php版本是5.4.12,要下载版本号为5.4.xx的php源码, 比如我的php版本为5.4.32, 以此版本为例。下载php源码 wget http://museum.php.net/php5/php-5.4.32.tar.gz 解压 tar zxvf php-5.4.32.tar.gzcd php-5.4.32/ext ./ext_skel --extname=crc64cd crc64vim crc64.c

    在 const zend_function_entry crc64_functions[] = {中增加

    PHP_FE(crc64_sum, NULL)

    在PHP_FUNCTION(confirm_crc64_compiled)上面增加下面代码

    PHP_FUNCTION(crc64_sum) { char *data; int data_len; char *init_crc64; int init_crc64_len; char result[100]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &init_crc64, &init_crc64_len, &data, &data_len) == FAILURE) { return; } crc64_init_once(); crc64(init_crc64, data, result, data_len); RETURN_STRINGL(result, strlen(result), 1); } 对php7来说, RETURN_STRINGL由三个参数改为两个参数, 如果你的是php7, 上句为 RETURN_STRINGL(result, strlen(result));vim ./php_crc64.h

    找到PHP_FUNCTION(confirm_crc64_compiled); 在上面添加一行

    PHP_FUNCTION(crc64_sum); 把oss提供的c语言实现的crc64代码拷贝到当前目录下 cp crc64_ecma.c ./vim config.m4找到PHP_ARG_ENABLE这一行, 把这行及下面两行的注释去掉。dnl就是注释的意思,修改后如下: PHP_ARG_WITH(crc64, for crc64 support, Make sure that the comment is aligned: [ --with-crc64 Include crc64 support]) 找到PHP_NEW_EXTENSION这行,修改后如下: PHP_NEW_EXTENSION(crc64, crc64.c crc64_ecma.c, $ext_shared)

    phpize ./configure make sudo make install 依次执行后可以检查一下, 这三个命令后会生成一个crc64.so文件并安装到 $extension_dir中,可以用 php -i | grep extension_dir 找到扩展目录。对于我这里就是/usr/lib64/php/modules目录, ll /usr/lib64/php/modules/crc64.so 果然在里面。

    vim /etc/php.ini 找到 ; Dynamic Extensions, 在下面添加一行:

    extension=crc64.so

    这样整个php嵌入c语言就完成了。使用php -m检验下成果, 发现crc64出现在模块列表中,这说明php嵌入c动态库成功。

    打开oss php sdk crc64校验的开关vim samples/Common.php

    找到$ossClient = new OssClient... 这行, 增加两个参数, 修改后如下:$ossClient = new OssClient(self::accessKeyId, self::accessKeySecret, self::endpoint, false, NULL, true); 这样sample下的示例就会打开crc64校验进行上传或下载。

    最新回复(0)