閱讀914 返回首頁    go 阿裏雲 go 技術社區[雲棲]


在 oss php sdk進行crc64校驗

背景

  • 使用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 https://museum.php.net/php5/php-5.4.32.tar.gz

  • 解壓
    tar zxvf php-5.4.32.tar.gz

  • cd php-5.4.32/ext
    ./ext_skel --extname=crc64

  • cd crc64
    vim 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校驗進行上傳或下載。

最後更新:2017-04-13 09:30:23

  上一篇:go java培訓-對想學JAVA的建議
  下一篇:go 簡單爬取天眼查數據 附代碼