Remove whyrusleeping/chunker from godeps
License: MIT Signed-off-by: Hector Sanjuan <hector@protocol.ai>
Hector Sanjuan committed
Feb 5, 2018 at 21:25 UTC
7aa1ab5368f1aff33f3e60090e510664c7ad2d18
9 files changed
-1457
Godeps/Godeps.json
-4
@@ -56,10 +56,6 @@
56
{
57
"ImportPath": "github.com/texttheater/golang-levenshtein/levenshtein",
58
"Rev": "dfd657628c58d3eeaa26391097853b2473c8b94e"
59
- },
60
- {
61
- "ImportPath": "github.com/whyrusleeping/chunker",
62
- "Rev": "537e901819164627ca4bb5ce4e3faa8ce7956564"
59
}
60
]
61
}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/.travis.yml
deleted
-10
@@ -1,10 +0,0 @@
1
-language: go
2
-sudo: false
3
-
4
-go:
5
- - 1.3.3
6
- - 1.4.2
7
-
8
-os:
9
- - linux
10
- - osx
Godeps/_workspace/src/github.com/whyrusleeping/chunker/LICENSE
deleted
-23
@@ -1,23 +0,0 @@
1
-Copyright (c) 2014, Alexander Neumann <alexander@bumpern.de>
2
-All rights reserved.
3
-
4
-Redistribution and use in source and binary forms, with or without
5
-modification, are permitted provided that the following conditions are met:
6
-
7
-1. Redistributions of source code must retain the above copyright notice, this
8
- list of conditions and the following disclaimer.
9
-
10
-2. Redistributions in binary form must reproduce the above copyright notice,
11
- this list of conditions and the following disclaimer in the documentation
12
- and/or other materials provided with the distribution.
13
-
14
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Godeps/_workspace/src/github.com/whyrusleeping/chunker/README.md
deleted
-7
@@ -1,7 +0,0 @@
1
-[](https://travis-ci.org/restic/chunker)
2
-
3
-Content Defined Chunking (CDC) based on a rolling Rabin Checksum.
4
-
5
-Part of https://github.com/restic/restic.
6
-
7
-Better README will follow soon.
Godeps/_workspace/src/github.com/whyrusleeping/chunker/chunker.go
deleted
-370
@@ -1,370 +0,0 @@
1
-package chunker
2
-
3
-import (
4
- "errors"
5
- "hash"
6
- "io"
7
- "math"
8
- "sync"
9
-)
10
-
11
-const (
12
- KiB = 1024
13
- MiB = 1024 * KiB
14
-
15
- // WindowSize is the size of the sliding window.
16
- windowSize = 16
17
-
18
- chunkerBufSize = 512 * KiB
19
-)
20
-
21
-var bufPool = sync.Pool{
22
- New: func() interface{} { return make([]byte, chunkerBufSize) },
23
-}
24
-
25
-type tables struct {
26
- out [256]Pol
27
- mod [256]Pol
28
-}
29
-
30
-// cache precomputed tables, these are read-only anyway
31
-var cache struct {
32
- entries map[Pol]*tables
33
- sync.Mutex
34
-}
35
-
36
-func init() {
37
- cache.entries = make(map[Pol]*tables)
38
-}
39
-
40
-// Chunk is one content-dependent chunk of bytes whose end was cut when the
41
-// Rabin Fingerprint had the value stored in Cut.
42
-type Chunk struct {
43
- Start uint64
44
- Length uint64
45
- Cut uint64
46
- Digest []byte
47
- Data []byte
48
-}
49
-
50
-func (c Chunk) Reader(r io.ReaderAt) io.Reader {
51
- return io.NewSectionReader(r, int64(c.Start), int64(c.Length))
52
-}
53
-
54
-// Chunker splits content with Rabin Fingerprints.
55
-type Chunker struct {
56
- pol Pol
57
- polShift uint64
58
- tables *tables
59
-
60
- rd io.Reader
61
- closed bool
62
-
63
- chunkbuf []byte
64
-
65
- window [windowSize]byte
66
- wpos int
67
-
68
- buf []byte
69
- bpos uint64
70
- bmax uint64
71
-
72
- start uint64
73
- count uint64
74
- pos uint64
75
-
76
- pre uint64 // wait for this many bytes before start calculating an new chunk
77
-
78
- digest uint64
79
- h hash.Hash
80
-
81
- sizeMask uint64
82
-
83
- // minimal and maximal size of the outputted blocks
84
- MinSize uint64
85
- MaxSize uint64
86
-}
87
-
88
-// New returns a new Chunker based on polynomial p that reads from rd
89
-// with bufsize and pass all data to hash along the way.
90
-func New(rd io.Reader, pol Pol, h hash.Hash, avSize, min, max uint64) *Chunker {
91
-
92
- sizepow := uint(math.Log2(float64(avSize)))
93
-
94
- c := &Chunker{
95
- buf: bufPool.Get().([]byte),
96
- h: h,
97
- pol: pol,
98
- rd: rd,
99
- chunkbuf: make([]byte, 0, max),
100
- sizeMask: (1 << sizepow) - 1,
101
-
102
- MinSize: min,
103
- MaxSize: max,
104
- }
105
-
106
- c.reset()
107
-
108
- return c
109
-}
110
-
111
-func (c *Chunker) reset() {
112
- c.polShift = uint64(c.pol.Deg() - 8)
113
- c.fillTables()
114
-
115
- for i := 0; i < windowSize; i++ {
116
- c.window[i] = 0
117
- }
118
-
119
- c.closed = false
120
- c.digest = 0
121
- c.wpos = 0
122
- c.count = 0
123
- c.slide(1)
124
- c.start = c.pos
125
-
126
- if c.h != nil {
127
- c.h.Reset()
128
- }
129
-
130
- // do not start a new chunk unless at least MinSize bytes have been read
131
- c.pre = c.MinSize - windowSize
132
-}
133
-
134
-// Calculate out_table and mod_table for optimization. Must be called only
135
-// once. This implementation uses a cache in the global variable cache.
136
-func (c *Chunker) fillTables() {
137
- // if polynomial hasn't been specified, do not compute anything for now
138
- if c.pol == 0 {
139
- return
140
- }
141
-
142
- // test if the tables are cached for this polynomial
143
- cache.Lock()
144
- defer cache.Unlock()
145
- if t, ok := cache.entries[c.pol]; ok {
146
- c.tables = t
147
- return
148
- }
149
-
150
- // else create a new entry
151
- c.tables = &tables{}
152
- cache.entries[c.pol] = c.tables
153
-
154
- // calculate table for sliding out bytes. The byte to slide out is used as
155
- // the index for the table, the value contains the following:
156
- // out_table[b] = Hash(b || 0 || ... || 0)
157
- // \ windowsize-1 zero bytes /
158
- // To slide out byte b_0 for window size w with known hash
159
- // H := H(b_0 || ... || b_w), it is sufficient to add out_table[b_0]:
160
- // H(b_0 || ... || b_w) + H(b_0 || 0 || ... || 0)
161
- // = H(b_0 + b_0 || b_1 + 0 || ... || b_w + 0)
162
- // = H( 0 || b_1 || ... || b_w)
163
- //
164
- // Afterwards a new byte can be shifted in.
165
- for b := 0; b < 256; b++ {
166
- var h Pol
167
-
168
- h = appendByte(h, byte(b), c.pol)
169
- for i := 0; i < windowSize-1; i++ {
170
- h = appendByte(h, 0, c.pol)
171
- }
172
- c.tables.out[b] = h
173
- }
174
-
175
- // calculate table for reduction mod Polynomial
176
- k := c.pol.Deg()
177
- for b := 0; b < 256; b++ {
178
- // mod_table[b] = A | B, where A = (b(x) * x^k mod pol) and B = b(x) * x^k
179
- //
180
- // The 8 bits above deg(Polynomial) determine what happens next and so
181
- // these bits are used as a lookup to this table. The value is split in
182
- // two parts: Part A contains the result of the modulus operation, part
183
- // B is used to cancel out the 8 top bits so that one XOR operation is
184
- // enough to reduce modulo Polynomial
185
- c.tables.mod[b] = Pol(uint64(b)<<uint64(k)).Mod(c.pol) | (Pol(b) << uint64(k))
186
- }
187
-}
188
-
189
-func (c *Chunker) nextBytes() []byte {
190
- data := dupBytes(c.chunkbuf[:c.count])
191
- n := copy(c.chunkbuf, c.chunkbuf[c.count:])
192
- c.chunkbuf = c.chunkbuf[:n]
193
-
194
- return data
195
-}
196
-
197
-// Next returns the position and length of the next chunk of data. If an error
198
-// occurs while reading, the error is returned with a nil chunk. The state of
199
-// the current chunk is undefined. When the last chunk has been returned, all
200
-// subsequent calls yield a nil chunk and an io.EOF error.
201
-func (c *Chunker) Next() (*Chunk, error) {
202
- if c.tables == nil {
203
- return nil, errors.New("polynomial is not set")
204
- }
205
-
206
- for {
207
- if c.bpos >= c.bmax {
208
- n, err := io.ReadFull(c.rd, c.buf[:])
209
- c.chunkbuf = append(c.chunkbuf, c.buf[:n]...)
210
-
211
- if err == io.ErrUnexpectedEOF {
212
- err = nil
213
- }
214
-
215
- // io.ReadFull only returns io.EOF when no bytes could be read. If
216
- // this is the case and we're in this branch, there are no more
217
- // bytes to buffer, so this was the last chunk. If a different
218
- // error has occurred, return that error and abandon the current
219
- // chunk.
220
- if err == io.EOF && !c.closed {
221
- c.closed = true
222
-
223
- // return the buffer to the pool
224
- bufPool.Put(c.buf)
225
-
226
- data := c.nextBytes()
227
-
228
- // return current chunk, if any bytes have been processed
229
- if c.count > 0 {
230
- return &Chunk{
231
- Start: c.start,
232
- Length: c.count,
233
- Cut: c.digest,
234
- Digest: c.hashDigest(),
235
- Data: data,
236
- }, nil
237
- }
238
- }
239
-
240
- if err != nil {
241
- return nil, err
242
- }
243
-
244
- c.bpos = 0
245
- c.bmax = uint64(n)
246
- }
247
-
248
- // check if bytes have to be dismissed before starting a new chunk
249
- if c.pre > 0 {
250
- n := c.bmax - c.bpos
251
- if c.pre > uint64(n) {
252
- c.pre -= uint64(n)
253
- c.updateHash(c.buf[c.bpos:c.bmax])
254
-
255
- c.count += uint64(n)
256
- c.pos += uint64(n)
257
- c.bpos = c.bmax
258
-
259
- continue
260
- }
261
-
262
- c.updateHash(c.buf[c.bpos : c.bpos+c.pre])
263
-
264
- c.bpos += c.pre
265
- c.count += c.pre
266
- c.pos += c.pre
267
- c.pre = 0
268
- }
269
-
270
- add := c.count
271
- for _, b := range c.buf[c.bpos:c.bmax] {
272
- // inline c.slide(b) and append(b) to increase performance
273
- out := c.window[c.wpos]
274
- c.window[c.wpos] = b
275
- c.digest ^= uint64(c.tables.out[out])
276
- c.wpos = (c.wpos + 1) % windowSize
277
-
278
- // c.append(b)
279
- index := c.digest >> c.polShift
280
- c.digest <<= 8
281
- c.digest |= uint64(b)
282
-
283
- c.digest ^= uint64(c.tables.mod[index])
284
- // end inline
285
-
286
- add++
287
- if add < c.MinSize {
288
- continue
289
- }
290
-
291
- if (c.digest&c.sizeMask) == 0 || add >= c.MaxSize {
292
- i := add - c.count - 1
293
- c.updateHash(c.buf[c.bpos : c.bpos+uint64(i)+1])
294
- c.count = add
295
- c.pos += uint64(i) + 1
296
- c.bpos += uint64(i) + 1
297
-
298
- data := c.nextBytes()
299
-
300
- chunk := &Chunk{
301
- Start: c.start,
302
- Length: c.count,
303
- Cut: c.digest,
304
- Digest: c.hashDigest(),
305
- Data: data,
306
- }
307
-
308
- c.reset()
309
-
310
- return chunk, nil
311
- }
312
- }
313
-
314
- steps := c.bmax - c.bpos
315
- if steps > 0 {
316
- c.updateHash(c.buf[c.bpos : c.bpos+steps])
317
- }
318
- c.count += steps
319
- c.pos += steps
320
- c.bpos = c.bmax
321
- }
322
-}
323
-
324
-func dupBytes(b []byte) []byte {
325
- out := make([]byte, len(b))
326
- copy(out, b)
327
- return out
328
-}
329
-
330
-func (c *Chunker) updateHash(data []byte) {
331
- if c.h != nil {
332
- // the hashes from crypto/sha* do not return an error
333
- _, err := c.h.Write(data)
334
- if err != nil {
335
- panic(err)
336
- }
337
- }
338
-}
339
-
340
-func (c *Chunker) hashDigest() []byte {
341
- if c.h == nil {
342
- return nil
343
- }
344
-
345
- return c.h.Sum(nil)
346
-}
347
-
348
-func (c *Chunker) append(b byte) {
349
- index := c.digest >> c.polShift
350
- c.digest <<= 8
351
- c.digest |= uint64(b)
352
-
353
- c.digest ^= uint64(c.tables.mod[index])
354
-}
355
-
356
-func (c *Chunker) slide(b byte) {
357
- out := c.window[c.wpos]
358
- c.window[c.wpos] = b
359
- c.digest ^= uint64(c.tables.out[out])
360
- c.wpos = (c.wpos + 1) % windowSize
361
-
362
- c.append(b)
363
-}
364
-
365
-func appendByte(hash Pol, b byte, pol Pol) Pol {
366
- hash <<= 8
367
- hash |= Pol(b)
368
-
369
- return hash.Mod(pol)
370
-}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/chunker_test.go
deleted
-298
@@ -1,298 +0,0 @@
1
-package chunker_test
2
-
3
-import (
4
- "bytes"
5
- "crypto/md5"
6
- "crypto/sha256"
7
- "encoding/hex"
8
- "hash"
9
- "io"
10
- "io/ioutil"
11
- "math/rand"
12
- "testing"
13
- "time"
14
-
15
- "github.com/restic/chunker"
16
- . "github.com/restic/restic/test"
17
-)
18
-
19
-func parseDigest(s string) []byte {
20
- d, err := hex.DecodeString(s)
21
- if err != nil {
22
- panic(err)
23
- }
24
-
25
- return d
26
-}
27
-
28
-type chunk struct {
29
- Length uint
30
- CutFP uint64
31
- Digest []byte
32
-}
33
-
34
-// polynomial used for all the tests below
35
-const testPol = chunker.Pol(0x3DA3358B4DC173)
36
-
37
-// created for 32MB of random data out of math/rand's Uint32() seeded by
38
-// constant 23
39
-//
40
-// chunking configuration:
41
-// window size 64, avg chunksize 1<<20, min chunksize 1<<19, max chunksize 1<<23
42
-// polynom 0x3DA3358B4DC173
43
-var chunks1 = []chunk{
44
- chunk{2163460, 0x000b98d4cdf00000, parseDigest("4b94cb2cf293855ea43bf766731c74969b91aa6bf3c078719aabdd19860d590d")},
45
- chunk{643703, 0x000d4e8364d00000, parseDigest("5727a63c0964f365ab8ed2ccf604912f2ea7be29759a2b53ede4d6841e397407")},
46
- chunk{1528956, 0x0015a25c2ef00000, parseDigest("a73759636a1e7a2758767791c69e81b69fb49236c6929e5d1b654e06e37674ba")},
47
- chunk{1955808, 0x00102a8242e00000, parseDigest("c955fb059409b25f07e5ae09defbbc2aadf117c97a3724e06ad4abd2787e6824")},
48
- chunk{2222372, 0x00045da878000000, parseDigest("6ba5e9f7e1b310722be3627716cf469be941f7f3e39a4c3bcefea492ec31ee56")},
49
- chunk{2538687, 0x00198a8179900000, parseDigest("8687937412f654b5cfe4a82b08f28393a0c040f77c6f95e26742c2fc4254bfde")},
50
- chunk{609606, 0x001d4e8d17100000, parseDigest("5da820742ff5feb3369112938d3095785487456f65a8efc4b96dac4be7ebb259")},
51
- chunk{1205738, 0x000a7204dd600000, parseDigest("cc70d8fad5472beb031b1aca356bcab86c7368f40faa24fe5f8922c6c268c299")},
52
- chunk{959742, 0x00183e71e1400000, parseDigest("4065bdd778f95676c92b38ac265d361f81bff17d76e5d9452cf985a2ea5a4e39")},
53
- chunk{4036109, 0x001fec043c700000, parseDigest("b9cf166e75200eb4993fc9b6e22300a6790c75e6b0fc8f3f29b68a752d42f275")},
54
- chunk{1525894, 0x000b1574b1500000, parseDigest("2f238180e4ca1f7520a05f3d6059233926341090f9236ce677690c1823eccab3")},
55
- chunk{1352720, 0x00018965f2e00000, parseDigest("afd12f13286a3901430de816e62b85cc62468c059295ce5888b76b3af9028d84")},
56
- chunk{811884, 0x00155628aa100000, parseDigest("42d0cdb1ee7c48e552705d18e061abb70ae7957027db8ae8db37ec756472a70a")},
57
- chunk{1282314, 0x001909a0a1400000, parseDigest("819721c2457426eb4f4c7565050c44c32076a56fa9b4515a1c7796441730eb58")},
58
- chunk{1318021, 0x001cceb980000000, parseDigest("842eb53543db55bacac5e25cb91e43cc2e310fe5f9acc1aee86bdf5e91389374")},
59
- chunk{948640, 0x0011f7a470a00000, parseDigest("b8e36bf7019bb96ac3fb7867659d2167d9d3b3148c09fe0de45850b8fe577185")},
60
- chunk{645464, 0x00030ce2d9400000, parseDigest("5584bd27982191c3329f01ed846bfd266e96548dfa87018f745c33cfc240211d")},
61
- chunk{533758, 0x0004435c53c00000, parseDigest("4da778a25b72a9a0d53529eccfe2e5865a789116cb1800f470d8df685a8ab05d")},
62
- chunk{1128303, 0x0000c48517800000, parseDigest("08c6b0b38095b348d80300f0be4c5184d2744a17147c2cba5cc4315abf4c048f")},
63
- chunk{800374, 0x000968473f900000, parseDigest("820284d2c8fd243429674c996d8eb8d3450cbc32421f43113e980f516282c7bf")},
64
- chunk{2453512, 0x001e197c92600000, parseDigest("5fa870ed107c67704258e5e50abe67509fb73562caf77caa843b5f243425d853")},
65
- chunk{2651975, 0x000ae6c868000000, parseDigest("181347d2bbec32bef77ad5e9001e6af80f6abcf3576549384d334ee00c1988d8")},
66
- chunk{237392, 0x0000000000000001, parseDigest("fcd567f5d866357a8e299fd5b2359bb2c8157c30395229c4e9b0a353944a7978")},
67
-}
68
-
69
-// test if nullbytes are correctly split, even if length is a multiple of MinSize.
70
-var chunks2 = []chunk{
71
- chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
72
- chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
73
- chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
74
- chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
75
-}
76
-
77
-func testWithData(t *testing.T, chnker *chunker.Chunker, testChunks []chunk) []*chunker.Chunk {
78
- chunks := []*chunker.Chunk{}
79
-
80
- pos := uint(0)
81
- for i, chunk := range testChunks {
82
- c, err := chnker.Next()
83
-
84
- if err != nil {
85
- t.Fatalf("Error returned with chunk %d: %v", i, err)
86
- }
87
-
88
- if c == nil {
89
- t.Fatalf("Nil chunk returned")
90
- }
91
-
92
- if c != nil {
93
- if c.Start != pos {
94
- t.Fatalf("Start for chunk %d does not match: expected %d, got %d",
95
- i, pos, c.Start)
96
- }
97
-
98
- if c.Length != chunk.Length {
99
- t.Fatalf("Length for chunk %d does not match: expected %d, got %d",
100
- i, chunk.Length, c.Length)
101
- }
102
-
103
- if c.Cut != chunk.CutFP {
104
- t.Fatalf("Cut fingerprint for chunk %d/%d does not match: expected %016x, got %016x",
105
- i, len(chunks)-1, chunk.CutFP, c.Cut)
106
- }
107
-
108
- if c.Digest != nil && !bytes.Equal(c.Digest, chunk.Digest) {
109
- t.Fatalf("Digest fingerprint for chunk %d/%d does not match: expected %02x, got %02x",
110
- i, len(chunks)-1, chunk.Digest, c.Digest)
111
- }
112
-
113
- pos += c.Length
114
- chunks = append(chunks, c)
115
- }
116
- }
117
-
118
- c, err := chnker.Next()
119
-
120
- if c != nil {
121
- t.Fatal("additional non-nil chunk returned")
122
- }
123
-
124
- if err != io.EOF {
125
- t.Fatal("wrong error returned after last chunk")
126
- }
127
-
128
- return chunks
129
-}
130
-
131
-func getRandom(seed, count int) []byte {
132
- buf := make([]byte, count)
133
-
134
- rnd := rand.New(rand.NewSource(23))
135
- for i := 0; i < count; i += 4 {
136
- r := rnd.Uint32()
137
- buf[i] = byte(r)
138
- buf[i+1] = byte(r >> 8)
139
- buf[i+2] = byte(r >> 16)
140
- buf[i+3] = byte(r >> 24)
141
- }
142
-
143
- return buf
144
-}
145
-
146
-func TestChunker(t *testing.T) {
147
- // setup data source
148
- buf := getRandom(23, 32*1024*1024)
149
- ch := chunker.New(bytes.NewReader(buf), testPol, sha256.New())
150
- chunks := testWithData(t, ch, chunks1)
151
-
152
- // test reader
153
- for i, c := range chunks {
154
- rd := c.Reader(bytes.NewReader(buf))
155
-
156
- h := sha256.New()
157
- n, err := io.Copy(h, rd)
158
- if err != nil {
159
- t.Fatalf("io.Copy(): %v", err)
160
- }
161
-
162
- if uint(n) != chunks1[i].Length {
163
- t.Fatalf("reader returned wrong number of bytes: expected %d, got %d",
164
- chunks1[i].Length, n)
165
- }
166
-
167
- d := h.Sum(nil)
168
- if !bytes.Equal(d, chunks1[i].Digest) {
169
- t.Fatalf("wrong hash returned: expected %02x, got %02x",
170
- chunks1[i].Digest, d)
171
- }
172
- }
173
-
174
- // setup nullbyte data source
175
- buf = bytes.Repeat([]byte{0}, len(chunks2)*chunker.MinSize)
176
- ch = chunker.New(bytes.NewReader(buf), testPol, sha256.New())
177
-
178
- testWithData(t, ch, chunks2)
179
-}
180
-
181
-func TestChunkerWithRandomPolynomial(t *testing.T) {
182
- // setup data source
183
- buf := getRandom(23, 32*1024*1024)
184
-
185
- // generate a new random polynomial
186
- start := time.Now()
187
- p, err := chunker.RandomPolynomial()
188
- OK(t, err)
189
- t.Logf("generating random polynomial took %v", time.Since(start))
190
-
191
- start = time.Now()
192
- ch := chunker.New(bytes.NewReader(buf), p, sha256.New())
193
- t.Logf("creating chunker took %v", time.Since(start))
194
-
195
- // make sure that first chunk is different
196
- c, err := ch.Next()
197
-
198
- Assert(t, c.Cut != chunks1[0].CutFP,
199
- "Cut point is the same")
200
- Assert(t, c.Length != chunks1[0].Length,
201
- "Length is the same")
202
- Assert(t, !bytes.Equal(c.Digest, chunks1[0].Digest),
203
- "Digest is the same")
204
-}
205
-
206
-func TestChunkerWithoutHash(t *testing.T) {
207
- // setup data source
208
- buf := getRandom(23, 32*1024*1024)
209
-
210
- ch := chunker.New(bytes.NewReader(buf), testPol, nil)
211
- chunks := testWithData(t, ch, chunks1)
212
-
213
- // test reader
214
- for i, c := range chunks {
215
- rd := c.Reader(bytes.NewReader(buf))
216
-
217
- buf2, err := ioutil.ReadAll(rd)
218
- if err != nil {
219
- t.Fatalf("io.Copy(): %v", err)
220
- }
221
-
222
- if uint(len(buf2)) != chunks1[i].Length {
223
- t.Fatalf("reader returned wrong number of bytes: expected %d, got %d",
224
- chunks1[i].Length, uint(len(buf2)))
225
- }
226
-
227
- if uint(len(buf2)) != chunks1[i].Length {
228
- t.Fatalf("wrong number of bytes returned: expected %02x, got %02x",
229
- chunks[i].Length, len(buf2))
230
- }
231
-
232
- if !bytes.Equal(buf[c.Start:c.Start+c.Length], buf2) {
233
- t.Fatalf("invalid data for chunk returned: expected %02x, got %02x",
234
- buf[c.Start:c.Start+c.Length], buf2)
235
- }
236
- }
237
-
238
- // setup nullbyte data source
239
- buf = bytes.Repeat([]byte{0}, len(chunks2)*chunker.MinSize)
240
- ch = chunker.New(bytes.NewReader(buf), testPol, sha256.New())
241
-
242
- testWithData(t, ch, chunks2)
243
-}
244
-
245
-func benchmarkChunker(b *testing.B, hash hash.Hash) {
246
- size := 10 * 1024 * 1024
247
- rd := bytes.NewReader(getRandom(23, size))
248
-
249
- b.ResetTimer()
250
- b.SetBytes(int64(size))
251
-
252
- var chunks int
253
- for i := 0; i < b.N; i++ {
254
- chunks = 0
255
-
256
- rd.Seek(0, 0)
257
- ch := chunker.New(rd, testPol, hash)
258
-
259
- for {
260
- _, err := ch.Next()
261
-
262
- if err == io.EOF {
263
- break
264
- }
265
-
266
- if err != nil {
267
- b.Fatalf("Unexpected error occurred: %v", err)
268
- }
269
-
270
- chunks++
271
- }
272
- }
273
-
274
- b.Logf("%d chunks, average chunk size: %d bytes", chunks, size/chunks)
275
-}
276
-
277
-func BenchmarkChunkerWithSHA256(b *testing.B) {
278
- benchmarkChunker(b, sha256.New())
279
-}
280
-
281
-func BenchmarkChunkerWithMD5(b *testing.B) {
282
- benchmarkChunker(b, md5.New())
283
-}
284
-
285
-func BenchmarkChunker(b *testing.B) {
286
- benchmarkChunker(b, nil)
287
-}
288
-
289
-func BenchmarkNewChunker(b *testing.B) {
290
- p, err := chunker.RandomPolynomial()
291
- OK(b, err)
292
-
293
- b.ResetTimer()
294
-
295
- for i := 0; i < b.N; i++ {
296
- chunker.New(bytes.NewBuffer(nil), p, nil)
297
- }
298
-}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/doc.go
deleted
-82
@@ -1,82 +0,0 @@
1
-// Copyright 2014 Alexander Neumann. All rights reserved.
2
-// Use of this source code is governed by a BSD-style
3
-// license that can be found in the LICENSE file.
4
-
5
-/*
6
-Package chunker implements Content Defined Chunking (CDC) based on a rolling
7
-Rabin Checksum.
8
-
9
-Choosing a Random Irreducible Polynomial
10
-
11
-The function RandomPolynomial() returns a new random polynomial of degree 53
12
-for use with the chunker. The degree 53 is chosen because it is the largest
13
-prime below 64-8 = 56, so that the top 8 bits of an uint64 can be used for
14
-optimising calculations in the chunker.
15
-
16
-A random polynomial is chosen selecting 64 random bits, masking away bits
17
-64..54 and setting bit 53 to one (otherwise the polynomial is not of the
18
-desired degree) and bit 0 to one (otherwise the polynomial is trivially
19
-reducible), so that 51 bits are chosen at random.
20
-
21
-This process is repeated until Irreducible() returns true, then this
22
-polynomials is returned. If this doesn't happen after 1 million tries, the
23
-function returns an error. The probability for selecting an irreducible
24
-polynomial at random is about 7.5% ( (2^53-2)/53 / 2^51), so the probability
25
-that no irreducible polynomial has been found after 100 tries is lower than
26
-0.04%.
27
-
28
-Verifying Irreducible Polynomials
29
-
30
-During development the results have been verified using the computational
31
-discrete algebra system GAP, which can be obtained from the website at
32
-http://www.gap-system.org/.
33
-
34
-For filtering a given list of polynomials in hexadecimal coefficient notation,
35
-the following script can be used:
36
-
37
- # create x over F_2 = GF(2)
38
- x := Indeterminate(GF(2), "x");
39
-
40
- # test if polynomial is irreducible, i.e. the number of factors is one
41
- IrredPoly := function (poly)
42
- return (Length(Factors(poly)) = 1);
43
- end;;
44
-
45
- # create a polynomial in x from the hexadecimal representation of the
46
- # coefficients
47
- Hex2Poly := function (s)
48
- return ValuePol(CoefficientsQadic(IntHexString(s), 2), x);
49
- end;;
50
-
51
- # list of candidates, in hex
52
- candidates := [ "3DA3358B4DC173" ];
53
-
54
- # create real polynomials
55
- L := List(candidates, Hex2Poly);
56
-
57
- # filter and display the list of irreducible polynomials contained in L
58
- Display(Filtered(L, x -> (IrredPoly(x))));
59
-
60
-All irreducible polynomials from the list are written to the output.
61
-
62
-Background Literature
63
-
64
-An introduction to Rabin Fingerprints/Checksums can be found in the following articles:
65
-
66
-Michael O. Rabin (1981): "Fingerprinting by Random Polynomials"
67
-http://www.xmailserver.org/rabin.pdf
68
-
69
-Ross N. Williams (1993): "A Painless Guide to CRC Error Detection Algorithms"
70
-http://www.zlib.net/crc_v3.txt
71
-
72
-Andrei Z. Broder (1993): "Some Applications of Rabin's Fingerprinting Method"
73
-http://www.xmailserver.org/rabin_apps.pdf
74
-
75
-Shuhong Gao and Daniel Panario (1997): "Tests and Constructions of Irreducible Polynomials over Finite Fields"
76
-http://www.math.clemson.edu/~sgao/papers/GP97a.pdf
77
-
78
-Andrew Kadatch, Bob Jenkins (2007): "Everything we know about CRC but afraid to forget"
79
-http://crcutil.googlecode.com/files/crc-doc.1.0.pdf
80
-
81
-*/
82
-package chunker
Godeps/_workspace/src/github.com/whyrusleeping/chunker/polynomials.go
deleted
-278
@@ -1,278 +0,0 @@
1
-package chunker
2
-
3
-import (
4
- "crypto/rand"
5
- "encoding/binary"
6
- "errors"
7
- "fmt"
8
- "strconv"
9
-)
10
-
11
-// Pol is a polynomial from F_2[X].
12
-type Pol uint64
13
-
14
-// Add returns x+y.
15
-func (x Pol) Add(y Pol) Pol {
16
- r := Pol(uint64(x) ^ uint64(y))
17
- return r
18
-}
19
-
20
-// mulOverflows returns true if the multiplication would overflow uint64.
21
-// Code by Rob Pike, see
22
-// https://groups.google.com/d/msg/golang-nuts/h5oSN5t3Au4/KaNQREhZh0QJ
23
-func mulOverflows(a, b Pol) bool {
24
- if a <= 1 || b <= 1 {
25
- return false
26
- }
27
- c := a.mul(b)
28
- d := c.Div(b)
29
- if d != a {
30
- return true
31
- }
32
-
33
- return false
34
-}
35
-
36
-func (x Pol) mul(y Pol) Pol {
37
- if x == 0 || y == 0 {
38
- return 0
39
- }
40
-
41
- var res Pol
42
- for i := 0; i <= y.Deg(); i++ {
43
- if (y & (1 << uint(i))) > 0 {
44
- res = res.Add(x << uint(i))
45
- }
46
- }
47
-
48
- return res
49
-}
50
-
51
-// Mul returns x*y. When an overflow occurs, Mul panics.
52
-func (x Pol) Mul(y Pol) Pol {
53
- if mulOverflows(x, y) {
54
- panic("multiplication would overflow uint64")
55
- }
56
-
57
- return x.mul(y)
58
-}
59
-
60
-// Deg returns the degree of the polynomial x. If x is zero, -1 is returned.
61
-func (x Pol) Deg() int {
62
- // the degree of 0 is -1
63
- if x == 0 {
64
- return -1
65
- }
66
-
67
- var mask Pol = (1 << 63)
68
- for i := 63; i >= 0; i-- {
69
- // test if bit i is set
70
- if x&mask > 0 {
71
- // this is the degree of x
72
- return i
73
- }
74
- mask >>= 1
75
- }
76
-
77
- // fall-through, return -1
78
- return -1
79
-}
80
-
81
-// String returns the coefficients in hex.
82
-func (x Pol) String() string {
83
- return "0x" + strconv.FormatUint(uint64(x), 16)
84
-}
85
-
86
-// Expand returns the string representation of the polynomial x.
87
-func (x Pol) Expand() string {
88
- if x == 0 {
89
- return "0"
90
- }
91
-
92
- s := ""
93
- for i := x.Deg(); i > 1; i-- {
94
- if x&(1<<uint(i)) > 0 {
95
- s += fmt.Sprintf("+x^%d", i)
96
- }
97
- }
98
-
99
- if x&2 > 0 {
100
- s += "+x"
101
- }
102
-
103
- if x&1 > 0 {
104
- s += "+1"
105
- }
106
-
107
- return s[1:]
108
-}
109
-
110
-// DivMod returns x / d = q, and remainder r,
111
-// see https://en.wikipedia.org/wiki/Division_algorithm
112
-func (x Pol) DivMod(d Pol) (Pol, Pol) {
113
- if x == 0 {
114
- return 0, 0
115
- }
116
-
117
- if d == 0 {
118
- panic("division by zero")
119
- }
120
-
121
- D := d.Deg()
122
- diff := x.Deg() - D
123
- if diff < 0 {
124
- return 0, x
125
- }
126
-
127
- var q Pol
128
- for diff >= 0 {
129
- m := d << uint(diff)
130
- q |= (1 << uint(diff))
131
- x = x.Add(m)
132
-
133
- diff = x.Deg() - D
134
- }
135
-
136
- return q, x
137
-}
138
-
139
-// Div returns the integer division result x / d.
140
-func (x Pol) Div(d Pol) Pol {
141
- q, _ := x.DivMod(d)
142
- return q
143
-}
144
-
145
-// Mod returns the remainder of x / d
146
-func (x Pol) Mod(d Pol) Pol {
147
- _, r := x.DivMod(d)
148
- return r
149
-}
150
-
151
-// I really dislike having a function that does not terminate, so specify a
152
-// really large upper bound for finding a new irreducible polynomial, and
153
-// return an error when no irreducible polynomial has been found within
154
-// randPolMaxTries.
155
-const randPolMaxTries = 1e6
156
-
157
-// RandomPolynomial returns a new random irreducible polynomial of degree 53
158
-// (largest prime number below 64-8). There are (2^53-2/53) irreducible
159
-// polynomials of degree 53 in F_2[X], c.f. Michael O. Rabin (1981):
160
-// "Fingerprinting by Random Polynomials", page 4. If no polynomial could be
161
-// found in one million tries, an error is returned.
162
-func RandomPolynomial() (Pol, error) {
163
- for i := 0; i < randPolMaxTries; i++ {
164
- var f Pol
165
-
166
- // choose polynomial at random
167
- err := binary.Read(rand.Reader, binary.LittleEndian, &f)
168
- if err != nil {
169
- return 0, err
170
- }
171
-
172
- // mask away bits above bit 53
173
- f &= Pol((1 << 54) - 1)
174
-
175
- // set highest and lowest bit so that the degree is 53 and the
176
- // polynomial is not trivially reducible
177
- f |= (1 << 53) | 1
178
-
179
- // test if f is irreducible
180
- if f.Irreducible() {
181
- return f, nil
182
- }
183
- }
184
-
185
- // If this is reached, we haven't found an irreducible polynomial in
186
- // randPolMaxTries. This error is very unlikely to occur.
187
- return 0, errors.New("unable to find new random irreducible polynomial")
188
-}
189
-
190
-// GCD computes the Greatest Common Divisor x and f.
191
-func (x Pol) GCD(f Pol) Pol {
192
- if f == 0 {
193
- return x
194
- }
195
-
196
- if x == 0 {
197
- return f
198
- }
199
-
200
- if x.Deg() < f.Deg() {
201
- x, f = f, x
202
- }
203
-
204
- return f.GCD(x.Mod(f))
205
-}
206
-
207
-// Irreducible returns true iff x is irreducible over F_2. This function
208
-// uses Ben Or's reducibility test.
209
-//
210
-// For details see "Tests and Constructions of Irreducible Polynomials over
211
-// Finite Fields".
212
-func (x Pol) Irreducible() bool {
213
- for i := 1; i <= x.Deg()/2; i++ {
214
- if x.GCD(qp(uint(i), x)) != 1 {
215
- return false
216
- }
217
- }
218
-
219
- return true
220
-}
221
-
222
-// MulMod computes x*f mod g
223
-func (x Pol) MulMod(f, g Pol) Pol {
224
- if x == 0 || f == 0 {
225
- return 0
226
- }
227
-
228
- var res Pol
229
- for i := 0; i <= f.Deg(); i++ {
230
- if (f & (1 << uint(i))) > 0 {
231
- a := x
232
- for j := 0; j < i; j++ {
233
- a = a.Mul(2).Mod(g)
234
- }
235
- res = res.Add(a).Mod(g)
236
- }
237
- }
238
-
239
- return res
240
-}
241
-
242
-// qp computes the polynomial (x^(2^p)-x) mod g. This is needed for the
243
-// reducibility test.
244
-func qp(p uint, g Pol) Pol {
245
- num := (1 << p)
246
- i := 1
247
-
248
- // start with x
249
- res := Pol(2)
250
-
251
- for i < num {
252
- // repeatedly square res
253
- res = res.MulMod(res, g)
254
- i *= 2
255
- }
256
-
257
- // add x
258
- return res.Add(2).Mod(g)
259
-}
260
-
261
-func (p Pol) MarshalJSON() ([]byte, error) {
262
- buf := strconv.AppendUint([]byte{'"'}, uint64(p), 16)
263
- buf = append(buf, '"')
264
- return buf, nil
265
-}
266
-
267
-func (p *Pol) UnmarshalJSON(data []byte) error {
268
- if len(data) < 2 {
269
- return errors.New("invalid string for polynomial")
270
- }
271
- n, err := strconv.ParseUint(string(data[1:len(data)-1]), 16, 64)
272
- if err != nil {
273
- return err
274
- }
275
- *p = Pol(n)
276
-
277
- return nil
278
-}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/polynomials_test.go
deleted
-385
@@ -1,385 +0,0 @@
1
-package chunker_test
2
-
3
-import (
4
- "strconv"
5
- "testing"
6
-
7
- "github.com/restic/chunker"
8
- . "github.com/restic/restic/test"
9
-)
10
-
11
-var polAddTests = []struct {
12
- x, y chunker.Pol
13
- sum chunker.Pol
14
-}{
15
- {23, 16, 23 ^ 16},
16
- {0x9a7e30d1e855e0a0, 0x670102a1f4bcd414, 0xfd7f32701ce934b4},
17
- {0x9a7e30d1e855e0a0, 0x9a7e30d1e855e0a0, 0},
18
-}
19
-
20
-func TestPolAdd(t *testing.T) {
21
- for _, test := range polAddTests {
22
- Equals(t, test.sum, test.x.Add(test.y))
23
- Equals(t, test.sum, test.y.Add(test.x))
24
- }
25
-}
26
-
27
-func parseBin(s string) chunker.Pol {
28
- i, err := strconv.ParseUint(s, 2, 64)
29
- if err != nil {
30
- panic(err)
31
- }
32
-
33
- return chunker.Pol(i)
34
-}
35
-
36
-var polMulTests = []struct {
37
- x, y chunker.Pol
38
- res chunker.Pol
39
-}{
40
- {1, 2, 2},
41
- {
42
- parseBin("1101"),
43
- parseBin("10"),
44
- parseBin("11010"),
45
- },
46
- {
47
- parseBin("1101"),
48
- parseBin("11"),
49
- parseBin("10111"),
50
- },
51
- {
52
- 0x40000000,
53
- 0x40000000,
54
- 0x1000000000000000,
55
- },
56
- {
57
- parseBin("1010"),
58
- parseBin("100100"),
59
- parseBin("101101000"),
60
- },
61
- {
62
- parseBin("100"),
63
- parseBin("11"),
64
- parseBin("1100"),
65
- },
66
- {
67
- parseBin("11"),
68
- parseBin("110101"),
69
- parseBin("1011111"),
70
- },
71
- {
72
- parseBin("10011"),
73
- parseBin("110101"),
74
- parseBin("1100001111"),
75
- },
76
-}
77
-
78
-func TestPolMul(t *testing.T) {
79
- for i, test := range polMulTests {
80
- m := test.x.Mul(test.y)
81
- Assert(t, test.res == m,
82
- "TestPolMul failed for test %d: %v * %v: want %v, got %v",
83
- i, test.x, test.y, test.res, m)
84
- m = test.y.Mul(test.x)
85
- Assert(t, test.res == test.y.Mul(test.x),
86
- "TestPolMul failed for %d: %v * %v: want %v, got %v",
87
- i, test.x, test.y, test.res, m)
88
- }
89
-}
90
-
91
-func TestPolMulOverflow(t *testing.T) {
92
- defer func() {
93
- // try to recover overflow error
94
- err := recover()
95
-
96
- if e, ok := err.(string); ok && e == "multiplication would overflow uint64" {
97
- return
98
- } else {
99
- t.Logf("invalid error raised: %v", err)
100
- // re-raise error if not overflow
101
- panic(err)
102
- }
103
- }()
104
-
105
- x := chunker.Pol(1 << 63)
106
- x.Mul(2)
107
- t.Fatal("overflow test did not panic")
108
-}
109
-
110
-var polDivTests = []struct {
111
- x, y chunker.Pol
112
- res chunker.Pol
113
-}{
114
- {10, 50, 0},
115
- {0, 1, 0},
116
- {
117
- parseBin("101101000"), // 0x168
118
- parseBin("1010"), // 0xa
119
- parseBin("100100"), // 0x24
120
- },
121
- {2, 2, 1},
122
- {
123
- 0x8000000000000000,
124
- 0x8000000000000000,
125
- 1,
126
- },
127
- {
128
- parseBin("1100"),
129
- parseBin("100"),
130
- parseBin("11"),
131
- },
132
- {
133
- parseBin("1100001111"),
134
- parseBin("10011"),
135
- parseBin("110101"),
136
- },
137
-}
138
-
139
-func TestPolDiv(t *testing.T) {
140
- for i, test := range polDivTests {
141
- m := test.x.Div(test.y)
142
- Assert(t, test.res == m,
143
- "TestPolDiv failed for test %d: %v * %v: want %v, got %v",
144
- i, test.x, test.y, test.res, m)
145
- }
146
-}
147
-
148
-var polModTests = []struct {
149
- x, y chunker.Pol
150
- res chunker.Pol
151
-}{
152
- {10, 50, 10},
153
- {0, 1, 0},
154
- {
155
- parseBin("101101001"),
156
- parseBin("1010"),
157
- parseBin("1"),
158
- },
159
- {2, 2, 0},
160
- {
161
- 0x8000000000000000,
162
- 0x8000000000000000,
163
- 0,
164
- },
165
- {
166
- parseBin("1100"),
167
- parseBin("100"),
168
- parseBin("0"),
169
- },
170
- {
171
- parseBin("1100001111"),
172
- parseBin("10011"),
173
- parseBin("0"),
174
- },
175
-}
176
-
177
-func TestPolModt(t *testing.T) {
178
- for _, test := range polModTests {
179
- Equals(t, test.res, test.x.Mod(test.y))
180
- }
181
-}
182
-
183
-func BenchmarkPolDivMod(t *testing.B) {
184
- f := chunker.Pol(0x2482734cacca49)
185
- g := chunker.Pol(0x3af4b284899)
186
-
187
- for i := 0; i < t.N; i++ {
188
- g.DivMod(f)
189
- }
190
-}
191
-
192
-func BenchmarkPolDiv(t *testing.B) {
193
- f := chunker.Pol(0x2482734cacca49)
194
- g := chunker.Pol(0x3af4b284899)
195
-
196
- for i := 0; i < t.N; i++ {
197
- g.Div(f)
198
- }
199
-}
200
-
201
-func BenchmarkPolMod(t *testing.B) {
202
- f := chunker.Pol(0x2482734cacca49)
203
- g := chunker.Pol(0x3af4b284899)
204
-
205
- for i := 0; i < t.N; i++ {
206
- g.Mod(f)
207
- }
208
-}
209
-
210
-func BenchmarkPolDeg(t *testing.B) {
211
- f := chunker.Pol(0x3af4b284899)
212
- d := f.Deg()
213
- if d != 41 {
214
- t.Fatalf("BenchmalPolDeg: Wrong degree %d returned, expected %d",
215
- d, 41)
216
- }
217
-
218
- for i := 0; i < t.N; i++ {
219
- f.Deg()
220
- }
221
-}
222
-
223
-func TestRandomPolynomial(t *testing.T) {
224
- _, err := chunker.RandomPolynomial()
225
- OK(t, err)
226
-}
227
-
228
-func BenchmarkRandomPolynomial(t *testing.B) {
229
- for i := 0; i < t.N; i++ {
230
- _, err := chunker.RandomPolynomial()
231
- OK(t, err)
232
- }
233
-}
234
-
235
-func TestExpandPolynomial(t *testing.T) {
236
- pol := chunker.Pol(0x3DA3358B4DC173)
237
- s := pol.Expand()
238
- Equals(t, "x^53+x^52+x^51+x^50+x^48+x^47+x^45+x^41+x^40+x^37+x^36+x^34+x^32+x^31+x^27+x^25+x^24+x^22+x^19+x^18+x^16+x^15+x^14+x^8+x^6+x^5+x^4+x+1", s)
239
-}
240
-
241
-var polIrredTests = []struct {
242
- f chunker.Pol
243
- irred bool
244
-}{
245
- {0x38f1e565e288df, false},
246
- {0x3DA3358B4DC173, true},
247
- {0x30a8295b9d5c91, false},
248
- {0x255f4350b962cb, false},
249
- {0x267f776110a235, false},
250
- {0x2f4dae10d41227, false},
251
- {0x2482734cacca49, true},
252
- {0x312daf4b284899, false},
253
- {0x29dfb6553d01d1, false},
254
- {0x3548245eb26257, false},
255
- {0x3199e7ef4211b3, false},
256
- {0x362f39017dae8b, false},
257
- {0x200d57aa6fdacb, false},
258
- {0x35e0a4efa1d275, false},
259
- {0x2ced55b026577f, false},
260
- {0x260b012010893d, false},
261
- {0x2df29cbcd59e9d, false},
262
- {0x3f2ac7488bd429, false},
263
- {0x3e5cb1711669fb, false},
264
- {0x226d8de57a9959, false},
265
- {0x3c8de80aaf5835, false},
266
- {0x2026a59efb219b, false},
267
- {0x39dfa4d13fb231, false},
268
- {0x3143d0464b3299, false},
269
-}
270
-
271
-func TestPolIrreducible(t *testing.T) {
272
- for _, test := range polIrredTests {
273
- Assert(t, test.f.Irreducible() == test.irred,
274
- "Irreducibility test for Polynomial %v failed: got %v, wanted %v",
275
- test.f, test.f.Irreducible(), test.irred)
276
- }
277
-}
278
-
279
-func BenchmarkPolIrreducible(b *testing.B) {
280
- // find first irreducible polynomial
281
- var pol chunker.Pol
282
- for _, test := range polIrredTests {
283
- if test.irred {
284
- pol = test.f
285
- break
286
- }
287
- }
288
-
289
- for i := 0; i < b.N; i++ {
290
- Assert(b, pol.Irreducible(),
291
- "Irreducibility test for Polynomial %v failed", pol)
292
- }
293
-}
294
-
295
-var polGCDTests = []struct {
296
- f1 chunker.Pol
297
- f2 chunker.Pol
298
- gcd chunker.Pol
299
-}{
300
- {10, 50, 2},
301
- {0, 1, 1},
302
- {
303
- parseBin("101101001"),
304
- parseBin("1010"),
305
- parseBin("1"),
306
- },
307
- {2, 2, 2},
308
- {
309
- parseBin("1010"),
310
- parseBin("11"),
311
- parseBin("11"),
312
- },
313
- {
314
- 0x8000000000000000,
315
- 0x8000000000000000,
316
- 0x8000000000000000,
317
- },
318
- {
319
- parseBin("1100"),
320
- parseBin("101"),
321
- parseBin("11"),
322
- },
323
- {
324
- parseBin("1100001111"),
325
- parseBin("10011"),
326
- parseBin("10011"),
327
- },
328
- {
329
- 0x3DA3358B4DC173,
330
- 0x3DA3358B4DC173,
331
- 0x3DA3358B4DC173,
332
- },
333
- {
334
- 0x3DA3358B4DC173,
335
- 0x230d2259defd,
336
- 1,
337
- },
338
- {
339
- 0x230d2259defd,
340
- 0x51b492b3eff2,
341
- parseBin("10011"),
342
- },
343
-}
344
-
345
-func TestPolGCD(t *testing.T) {
346
- for i, test := range polGCDTests {
347
- gcd := test.f1.GCD(test.f2)
348
- Assert(t, test.gcd == gcd,
349
- "GCD test %d (%+v) failed: got %v, wanted %v",
350
- i, test, gcd, test.gcd)
351
- gcd = test.f2.GCD(test.f1)
352
- Assert(t, test.gcd == gcd,
353
- "GCD test %d (%+v) failed: got %v, wanted %v",
354
- i, test, gcd, test.gcd)
355
- }
356
-}
357
-
358
-var polMulModTests = []struct {
359
- f1 chunker.Pol
360
- f2 chunker.Pol
361
- g chunker.Pol
362
- mod chunker.Pol
363
-}{
364
- {
365
- 0x1230,
366
- 0x230,
367
- 0x55,
368
- 0x22,
369
- },
370
- {
371
- 0x0eae8c07dbbb3026,
372
- 0xd5d6db9de04771de,
373
- 0xdd2bda3b77c9,
374
- 0x425ae8595b7a,
375
- },
376
-}
377
-
378
-func TestPolMulMod(t *testing.T) {
379
- for i, test := range polMulModTests {
380
- mod := test.f1.MulMod(test.f2, test.g)
381
- Assert(t, mod == test.mod,
382
- "MulMod test %d (%+v) failed: got %v, wanted %v",
383
- i, test, mod, test.mod)
384
- }
385
-}