2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-23 05:12:10 +00:00

Update chunker

This commit is contained in:
Alexander Neumann 2016-09-03 20:56:21 +02:00
parent 9ce40761c8
commit f744c3534d
4 changed files with 71 additions and 18 deletions

2
vendor/manifest vendored
View File

@ -46,7 +46,7 @@
{ {
"importpath": "github.com/restic/chunker", "importpath": "github.com/restic/chunker",
"repository": "https://github.com/restic/chunker", "repository": "https://github.com/restic/chunker",
"revision": "d1a97fa6e55ab338a8ceb769d72f856a56e9379a", "revision": "49e9b5212b022a1ab373faf981ed4f2fc807502a",
"branch": "master" "branch": "master"
}, },
{ {

View File

@ -175,6 +175,9 @@ func TestChunkerWithRandomPolynomial(t *testing.T) {
// make sure that first chunk is different // make sure that first chunk is different
c, err := ch.Next(nil) c, err := ch.Next(nil)
if err != nil {
t.Fatal(err.Error())
}
if c.Cut == chunks1[0].CutFP { if c.Cut == chunks1[0].CutFP {
t.Fatal("Cut point is the same") t.Fatal("Cut point is the same")

View File

@ -5,6 +5,7 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"io"
"strconv" "strconv"
) )
@ -64,18 +65,40 @@ func (x Pol) Deg() int {
return -1 return -1
} }
var mask Pol = (1 << 63) // see https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
for i := 63; i >= 0; i-- {
// test if bit i is set r := 0
if x&mask > 0 { if uint64(x)&0xffffffff00000000 > 0 {
// this is the degree of x x >>= 32
return i r |= 32
}
mask >>= 1
} }
// fall-through, return -1 if uint64(x)&0xffff0000 > 0 {
return -1 x >>= 16
r |= 16
}
if uint64(x)&0xff00 > 0 {
x >>= 8
r |= 8
}
if uint64(x)&0xf0 > 0 {
x >>= 4
r |= 4
}
if uint64(x)&0xc > 0 {
x >>= 2
r |= 2
}
if uint64(x)&0x2 > 0 {
x >>= 1
r |= 1
}
return r
} }
// String returns the coefficients in hex. // String returns the coefficients in hex.
@ -154,17 +177,25 @@ func (x Pol) Mod(d Pol) Pol {
// randPolMaxTries. // randPolMaxTries.
const randPolMaxTries = 1e6 const randPolMaxTries = 1e6
// RandomPolynomial returns a new random irreducible polynomial of degree 53 // RandomPolynomial returns a new random irreducible polynomial
// (largest prime number below 64-8). There are (2^53-2/53) irreducible // of degree 53 using the default System CSPRNG as source.
// polynomials of degree 53 in F_2[X], c.f. Michael O. Rabin (1981): // It is equivalent to calling DerivePolynomial(rand.Reader).
// "Fingerprinting by Random Polynomials", page 4. If no polynomial could be
// found in one million tries, an error is returned.
func RandomPolynomial() (Pol, error) { func RandomPolynomial() (Pol, error) {
return DerivePolynomial(rand.Reader)
}
// DerivePolynomial returns an irreducible polynomial of degree 53
// (largest prime number below 64-8) by reading bytes from source.
// There are (2^53-2/53) irreducible polynomials of degree 53 in
// F_2[X], c.f. Michael O. Rabin (1981): "Fingerprinting by Random
// Polynomials", page 4. If no polynomial could be found in one
// million tries, an error is returned.
func DerivePolynomial(source io.Reader) (Pol, error) {
for i := 0; i < randPolMaxTries; i++ { for i := 0; i < randPolMaxTries; i++ {
var f Pol var f Pol
// choose polynomial at random // choose polynomial at (pseudo)random
err := binary.Read(rand.Reader, binary.LittleEndian, &f) err := binary.Read(source, binary.LittleEndian, &f)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -150,6 +150,25 @@ func TestPolDiv(t *testing.T) {
} }
} }
func TestPolDeg(t *testing.T) {
var x Pol
if x.Deg() != -1 {
t.Errorf("deg(0) is not -1: %v", x.Deg())
}
x = 1
if x.Deg() != 0 {
t.Errorf("deg(1) is not 0: %v", x.Deg())
}
for i := 0; i < 64; i++ {
x = 1 << uint(i)
if x.Deg() != i {
t.Errorf("deg(1<<%d) is not %d: %v", i, i, x.Deg())
}
}
}
var polModTests = []struct { var polModTests = []struct {
x, y Pol x, y Pol
res Pol res Pol