Etag::calcSha1()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.0116

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 9
ccs 6
cts 7
cp 0.8571
crap 2.0116
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Qiniu;
4
5
use Qiniu\Config;
6
7
final class Etag
8
{
9 12
    private static function packArray($v, $a)
10
    {
11 12
        return call_user_func_array('pack', array_merge(array($v), (array)$a));
12
    }
13
14 12
    private static function blockCount($fsize)
15
    {
16 12
        return intval(($fsize + (Config::BLOCK_SIZE - 1)) / Config::BLOCK_SIZE);
17
    }
18
19 12
    private static function calcSha1($data)
20
    {
21 12
        $sha1Str = sha1($data, true);
22 12
        $err = error_get_last();
23 12
        if ($err !== null) {
24
            return array(null, $err);
25
        }
26 12
        $byteArray = unpack('C*', $sha1Str);
27 12
        return array($byteArray, null);
28
    }
29
30
31 15
    public static function sum($filename)
32
    {
33 15
        $fhandler = fopen($filename, 'r');
34 15
        $err = error_get_last();
35 15
        if ($err !== null) {
36
            return array(null, $err);
37
        }
38
39 15
        $fstat = fstat($fhandler);
40 15
        $fsize = $fstat['size'];
41 15
        if ((int)$fsize === 0) {
42 3
            fclose($fhandler);
43 3
            return array('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', null);
44
        }
45 12
        $blockCnt = self::blockCount($fsize);
46 12
        $sha1Buf = array();
47
48 12
        if ($blockCnt <= 1) {
49 6
            array_push($sha1Buf, 0x16);
50 6
            $fdata = fread($fhandler, Config::BLOCK_SIZE);
51 6
            if ($err !== null) {
52
                fclose($fhandler);
53
                return array(null, $err);
54
            }
55 6
            list($sha1Code,) = self::calcSha1($fdata);
56 6
            $sha1Buf = array_merge($sha1Buf, $sha1Code);
57 6
        } else {
58 6
            array_push($sha1Buf, 0x96);
59 6
            $sha1BlockBuf = array();
60 6
            for ($i = 0; $i < $blockCnt; $i++) {
61 6
                $fdata = fread($fhandler, Config::BLOCK_SIZE);
62 6
                list($sha1Code, $err) = self::calcSha1($fdata);
63 6
                if ($err !== null) {
64
                    fclose($fhandler);
65
                    return array(null, $err);
66
                }
67 6
                $sha1BlockBuf = array_merge($sha1BlockBuf, $sha1Code);
68 6
            }
69 6
            $tmpData = self::packArray('C*', $sha1BlockBuf);
70 6
            list($sha1Final,) = self::calcSha1($tmpData);
71 6
            $sha1Buf = array_merge($sha1Buf, $sha1Final);
72
        }
73 12
        $etag = \Qiniu\base64_urlSafeEncode(self::packArray('C*', $sha1Buf));
74 12
        return array($etag, null);
75
    }
76
}
77