Php:如何计算 zip 的 Adler32 校验和?

标签 php apache-flex compression zip adler32

我在服务器端结合使用 Paul Duncans php ZipStream ( http://pablotron.org/software/zipstream-php/ ) 来动态创建 zip,并在 Flex/Air 客户端结合使用 Fzip ( http://codeazur.com.br/lab/fzip/ )。

在 Air 中工作正常,但在浏览器中运行 Flex 时,zip 需要在 header 中包含 Adler32 校验和才能读取 FZip。

如何在 php 中计算 zip 的 Adler32 校验和?

使用 gzdeflate 进行压缩的 ZipStream 核心函数如下所示。

问候/乔纳斯

function add_file($name, $data, $opt = array(), $deflateLevel=0) {
    # compress data

    $zdata = gzdeflate($data, $deflateLevel);

    # calculate header attributes

    $crc  = crc32($data);
    $zlen = strlen($zdata);
    $len  = strlen($data);
    $meth = 0x08;

    # send file header
    $this->add_file_header($name, $opt, $meth, $crc, $zlen, $len);

    # print data
    $this->send($zdata);
}

private function add_file_header($name, $opt, $meth, $crc, $zlen, $len) {
    # strip leading slashes from file name
    # (fixes bug in windows archive viewer)
    $name = preg_replace('/^\\/+/', '', $name);

    # calculate name length
    $nlen = strlen($name);

    # create dos timestamp
    $opt['time'] = $opt['time'] ? $opt['time'] : time();
    $dts = $this->dostime($opt['time']);

    # build file header
    $fields = array(            # (from V.A of APPNOTE.TXT)
    array('V', 0x04034b50),     # local file header signature
    array('v', (6 << 8) + 3),   # version needed to extract
    array('v', 0x00),           # general purpose bit flag
    array('v', $meth),          # compresion method (deflate or store)
    array('V', $dts),           # dos timestamp
    array('V', $crc),           # crc32 of data
    array('V', $zlen),          # compressed data length
    array('V', $len),           # uncompressed data length
    array('v', $nlen),          # filename length
    array('v', 0),              # extra data len
    );

    # pack fields and calculate "total" length
    $ret = $this->pack_fields($fields);
    $cdr_len = strlen($ret) + $nlen + $zlen;

    # print header and filename
    $this->send($ret . $name);

    # add to central directory record and increment offset
    $this->add_to_cdr($name, $opt, $meth, $crc, $zlen, $len, $cdr_len);
}

最佳答案

翻译自example implementation in the Wikipedia article :

define('MOD_ADLER', 65521);

function adler32($data) {
    $a = 1; $b = 0; $len = strlen($data);
    for ($index = 0; $index < $len; ++$index) {
        $a = ($a + $data[$index]) % MOD_ADLER;
        $b = ($b + $a) % MOD_ADLER;
    }
    return ($b << 16) | $a;
}

并将该整数值转换为字节:

pack('H*', $checksum);

关于Php:如何计算 zip 的 Adler32 校验和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1316881/

相关文章:

javascript - 在 div 中隐藏/显示 swf?

actionscript-3 - TLFTextField 在 Flex 应用程序中自动获取设备字体

javascript - 如何使用 OpenLayers 在 map 顶部创建可单击的网格图层

php - 发送全局变量

php - 更新 mysql 数据库中的记录时,bind_param() 出错

compression - 流模式与 block 模式

python - 在 python 中下载大文件错误 : Compressed file ended before the end-of-stream marker was reached

php - MongoDB 作为 MySQL 缓存

javascript - 从 Javascript 调用 Flex/AS3 回调

Git 存储库压缩后比未压缩更大