OSDN Git Service

Create ossClient.go (#574)
[bytom/vapor.git] / vendor / github.com / aliyun / aliyun-oss-go-sdk / oss / crc.go
1 package oss
2
3 import (
4         "hash"
5         "hash/crc64"
6 )
7
8 // digest represents the partial evaluation of a checksum.
9 type digest struct {
10         crc uint64
11         tab *crc64.Table
12 }
13
14 // NewCRC creates a new hash.Hash64 computing the CRC64 checksum
15 // using the polynomial represented by the Table.
16 func NewCRC(tab *crc64.Table, init uint64) hash.Hash64 { return &digest{init, tab} }
17
18 // Size returns the number of bytes sum will return.
19 func (d *digest) Size() int { return crc64.Size }
20
21 // BlockSize returns the hash's underlying block size.
22 // The Write method must be able to accept any amount
23 // of data, but it may operate more efficiently if all writes
24 // are a multiple of the block size.
25 func (d *digest) BlockSize() int { return 1 }
26
27 // Reset resets the hash to its initial state.
28 func (d *digest) Reset() { d.crc = 0 }
29
30 // Write (via the embedded io.Writer interface) adds more data to the running hash.
31 // It never returns an error.
32 func (d *digest) Write(p []byte) (n int, err error) {
33         d.crc = crc64.Update(d.crc, d.tab, p)
34         return len(p), nil
35 }
36
37 // Sum64 returns CRC64 value.
38 func (d *digest) Sum64() uint64 { return d.crc }
39
40 // Sum returns hash value.
41 func (d *digest) Sum(in []byte) []byte {
42         s := d.Sum64()
43         return append(in, byte(s>>56), byte(s>>48), byte(s>>40), byte(s>>32), byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
44 }
45
46 // gf2Dim dimension of GF(2) vectors (length of CRC)
47 const gf2Dim int = 64
48
49 func gf2MatrixTimes(mat []uint64, vec uint64) uint64 {
50         var sum uint64
51         for i := 0; vec != 0; i++ {
52                 if vec&1 != 0 {
53                         sum ^= mat[i]
54                 }
55
56                 vec >>= 1
57         }
58         return sum
59 }
60
61 func gf2MatrixSquare(square []uint64, mat []uint64) {
62         for n := 0; n < gf2Dim; n++ {
63                 square[n] = gf2MatrixTimes(mat, mat[n])
64         }
65 }
66
67 // CRC64Combine combines CRC64
68 func CRC64Combine(crc1 uint64, crc2 uint64, len2 uint64) uint64 {
69         var even [gf2Dim]uint64 // Even-power-of-two zeros operator
70         var odd [gf2Dim]uint64  // Odd-power-of-two zeros operator
71
72         // Degenerate case
73         if len2 == 0 {
74                 return crc1
75         }
76
77         // Put operator for one zero bit in odd
78         odd[0] = crc64.ECMA // CRC64 polynomial
79         var row uint64 = 1
80         for n := 1; n < gf2Dim; n++ {
81                 odd[n] = row
82                 row <<= 1
83         }
84
85         // Put operator for two zero bits in even
86         gf2MatrixSquare(even[:], odd[:])
87
88         // Put operator for four zero bits in odd
89         gf2MatrixSquare(odd[:], even[:])
90
91         // Apply len2 zeros to crc1, first square will put the operator for one zero byte, eight zero bits, in even
92         for {
93                 // Apply zeros operator for this bit of len2
94                 gf2MatrixSquare(even[:], odd[:])
95
96                 if len2&1 != 0 {
97                         crc1 = gf2MatrixTimes(even[:], crc1)
98                 }
99
100                 len2 >>= 1
101
102                 // If no more bits set, then done
103                 if len2 == 0 {
104                         break
105                 }
106
107                 // Another iteration of the loop with odd and even swapped
108                 gf2MatrixSquare(odd[:], even[:])
109                 if len2&1 != 0 {
110                         crc1 = gf2MatrixTimes(odd[:], crc1)
111                 }
112                 len2 >>= 1
113
114                 // If no more bits set, then done
115                 if len2 == 0 {
116                         break
117                 }
118         }
119
120         // Return combined CRC
121         crc1 ^= crc2
122         return crc1
123 }