| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | <?phpnamespace Qiniu;use Qiniu\Config;final class Etag{    private static function packArray($v, $a)    {        return call_user_func_array('pack', array_merge(array($v), (array)$a));    }    private static function blockCount($fsize)    {        return intval(($fsize + (Config::BLOCK_SIZE - 1)) / Config::BLOCK_SIZE);    }    private static function calcSha1($data)    {        $sha1Str = sha1($data, true);        $err = error_get_last();        if ($err !== null) {            return array(null, $err);        }        $byteArray = unpack('C*', $sha1Str);        return array($byteArray, null);    }    public static function sum($filename)    {        $fhandler = fopen($filename, 'r');        $err = error_get_last();        if ($err !== null) {            return array(null, $err);        }        $fstat = fstat($fhandler);        $fsize = $fstat['size'];        if ((int)$fsize === 0) {            fclose($fhandler);            return array('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', null);        }        $blockCnt = self::blockCount($fsize);        $sha1Buf = array();        if ($blockCnt <= 1) {            array_push($sha1Buf, 0x16);            $fdata = fread($fhandler, Config::BLOCK_SIZE);            if ($err !== null) {                fclose($fhandler);                return array(null, $err);            }            list($sha1Code,) = self::calcSha1($fdata);            $sha1Buf = array_merge($sha1Buf, $sha1Code);        } else {            array_push($sha1Buf, 0x96);            $sha1BlockBuf = array();            for ($i = 0; $i < $blockCnt; $i++) {                $fdata = fread($fhandler, Config::BLOCK_SIZE);                list($sha1Code, $err) = self::calcSha1($fdata);                if ($err !== null) {                    fclose($fhandler);                    return array(null, $err);                }                $sha1BlockBuf = array_merge($sha1BlockBuf, $sha1Code);            }            $tmpData = self::packArray('C*', $sha1BlockBuf);            list($sha1Final,) = self::calcSha1($tmpData);            $sha1Buf = array_merge($sha1Buf, $sha1Final);        }        $etag = \Qiniu\base64_urlSafeEncode(self::packArray('C*', $sha1Buf));        return array($etag, null);    }}
 |