我在服务器端结合使用 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/