mirror of
https://github.com/octoleo/restic.git
synced 2024-11-23 05:12:10 +00:00
Update chunker
This commit is contained in:
parent
9ce40761c8
commit
f744c3534d
2
vendor/manifest
vendored
2
vendor/manifest
vendored
@ -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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user