mirror of
https://github.com/fumiama/unibase2n.git
synced 2026-06-05 00:32:47 +08:00
finish dec128blk1
This commit is contained in:
58
decode.go
58
decode.go
@@ -1,5 +1,63 @@
|
|||||||
package unibase2n
|
package unibase2n
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
)
|
||||||
|
|
||||||
func (bs Base) Decode(data []byte) []byte {
|
func (bs Base) Decode(data []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dec128blk1 for bit 1
|
||||||
|
// len(in)>0, len(in)%16==0, len(out)==len(in)/16
|
||||||
|
func dec128blk1(mask uint128be, in, out []byte) {
|
||||||
|
for i := range out {
|
||||||
|
c := i * 16
|
||||||
|
n := readuint128be(in[c : c+16])
|
||||||
|
one := u128one
|
||||||
|
n.subeq(mask)
|
||||||
|
sum := n.and(one)
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
n.shreq(16 - 1)
|
||||||
|
one.shleq(1)
|
||||||
|
sum.oreq(n.and(one))
|
||||||
|
out[i] = uint8(sum.b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dec64blk2 for bit 2
|
||||||
|
// len(in)!=0, len(out)==len(in)/8
|
||||||
|
func dec64blk2(mask uint64, in, out []byte) {
|
||||||
|
for i, n := range in {
|
||||||
|
c := i * 8
|
||||||
|
x := (uint64(n)<<42 | uint64(n)<<28 | uint64(n)<<14 | uint64(n)) & 0x00030003_00030003
|
||||||
|
binary.BigEndian.PutUint64(out[c:c+8], x+mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dec32blk4 for bit 4
|
||||||
|
// len(in)!=0, len(out)==len(in)/4
|
||||||
|
func dec32blk4(mask uint32, in, out []byte) {
|
||||||
|
for i, n := range in {
|
||||||
|
c := i * 4
|
||||||
|
x := (uint32(n)<<12 | uint32(n)) & 0x000f000f
|
||||||
|
binary.BigEndian.PutUint32(out[c:c+4], x+mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
22
decode_test.go
Normal file
22
decode_test.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package unibase2n
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDec128blk1(t *testing.T) {
|
||||||
|
var in, tmp [32]byte
|
||||||
|
_, err := rand.Read(in[:])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
n, _ := Base{bit: 1}.EncodeLen(32)
|
||||||
|
out := make([]byte, n)
|
||||||
|
enc16blk1(0x2333, in[:], out)
|
||||||
|
t.Log(out)
|
||||||
|
dec128blk1(uint128be{0x2333233323332333, 0x2333233323332333}, out[:], tmp[:])
|
||||||
|
assert.Equal(t, in, tmp)
|
||||||
|
}
|
||||||
@@ -57,7 +57,7 @@ func enc16blk1(mask uint16, in, out []byte) {
|
|||||||
func enc64blk2(mask uint64, in, out []byte) {
|
func enc64blk2(mask uint64, in, out []byte) {
|
||||||
for i, n := range in {
|
for i, n := range in {
|
||||||
c := i * 8
|
c := i * 8
|
||||||
x := (uint64(n)<<42 | uint64(n)<<28 | uint64(n)<<14 | uint64(n)) & 0x30003_00030003
|
x := (uint64(n)<<42 | uint64(n)<<28 | uint64(n)<<14 | uint64(n)) & 0x00030003_00030003
|
||||||
binary.BigEndian.PutUint64(out[c:c+8], x+mask)
|
binary.BigEndian.PutUint64(out[c:c+8], x+mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ func enc64blk2(mask uint64, in, out []byte) {
|
|||||||
func enc32blk4(mask uint32, in, out []byte) {
|
func enc32blk4(mask uint32, in, out []byte) {
|
||||||
for i, n := range in {
|
for i, n := range in {
|
||||||
c := i * 4
|
c := i * 4
|
||||||
x := (uint32(n)<<12 | uint32(n)) & 0xf000f
|
x := (uint32(n)<<12 | uint32(n)) & 0x000f000f
|
||||||
binary.BigEndian.PutUint32(out[c:c+4], x+mask)
|
binary.BigEndian.PutUint32(out[c:c+4], x+mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
uint128be.go
27
uint128be.go
@@ -12,6 +12,11 @@ type uint128be struct {
|
|||||||
b uint64
|
b uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
u128minusone = uint128be{0xffffffff_ffffffff, 0xffffffff_ffffffff}
|
||||||
|
u128one = uint128be{0, 1}
|
||||||
|
)
|
||||||
|
|
||||||
func readuint128be(b []byte) uint128be {
|
func readuint128be(b []byte) uint128be {
|
||||||
if len(b) < 16 {
|
if len(b) < 16 {
|
||||||
b = append(b, make([]byte, 16-len(b))...)
|
b = append(b, make([]byte, 16-len(b))...)
|
||||||
@@ -29,6 +34,20 @@ func (num *uint128be) addeq(n uint128be) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (num *uint128be) subeq(n uint128be) {
|
||||||
|
var b uint64
|
||||||
|
num.b, b = bits.Sub64(num.b, n.b, 0)
|
||||||
|
num.a, _ = bits.Sub64(num.a, n.a, b)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (num uint128be) sub(n uint128be) (r uint128be) {
|
||||||
|
var b uint64
|
||||||
|
r.b, b = bits.Sub64(num.b, n.b, 0)
|
||||||
|
r.a, _ = bits.Sub64(num.a, n.a, b)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// shreq only supports shifting 1 ~ 63 bits
|
// shreq only supports shifting 1 ~ 63 bits
|
||||||
func (num *uint128be) shreq(c uint8) {
|
func (num *uint128be) shreq(c uint8) {
|
||||||
mask := uint64(1)<<c - 1
|
mask := uint64(1)<<c - 1
|
||||||
@@ -37,6 +56,14 @@ func (num *uint128be) shreq(c uint8) {
|
|||||||
num.b = aout | (num.b >> c)
|
num.b = aout | (num.b >> c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shreq only supports shifting 1 ~ 63 bits
|
||||||
|
func (num *uint128be) shleq(c uint8) {
|
||||||
|
mask := (uint64(1)<<c - 1) << (64 - c)
|
||||||
|
bout := (num.b & mask) >> (64 - c)
|
||||||
|
num.b = num.b << c
|
||||||
|
num.a = bout | (num.a << c)
|
||||||
|
}
|
||||||
|
|
||||||
func (num *uint128be) andeq(n uint128be) {
|
func (num *uint128be) andeq(n uint128be) {
|
||||||
num.a &= n.a
|
num.a &= n.a
|
||||||
num.b &= n.b
|
num.b &= n.b
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ func TestUint128be(t *testing.T) {
|
|||||||
zero := readuint128be(make([]byte, 16))
|
zero := readuint128be(make([]byte, 16))
|
||||||
one := readuint128be([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
|
one := readuint128be([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
|
||||||
num := readuint128be(buf[:])
|
num := readuint128be(buf[:])
|
||||||
|
assert.Equal(t, zero.sub(one), num)
|
||||||
num.addeq(one)
|
num.addeq(one)
|
||||||
assert.Equal(t, num, zero)
|
assert.Equal(t, num, zero)
|
||||||
num.addeq(readuint128be([]byte{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef}))
|
num.addeq(readuint128be([]byte{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef}))
|
||||||
@@ -22,7 +23,9 @@ func TestUint128be(t *testing.T) {
|
|||||||
num.shreq(32)
|
num.shreq(32)
|
||||||
assert.Equal(t, num, uint128be{0x0000000000000012, 0x34567890abcdef12})
|
assert.Equal(t, num, uint128be{0x0000000000000012, 0x34567890abcdef12})
|
||||||
assert.Equal(t, num.String(), "0x1234567890abcdef12")
|
assert.Equal(t, num.String(), "0x1234567890abcdef12")
|
||||||
num.shreq(1)
|
num.shleq(8)
|
||||||
|
assert.Equal(t, num, uint128be{0x00000000000001234, 0x567890abcdef1200})
|
||||||
|
num.shreq(9)
|
||||||
// 因为 num.a 低 1 位为 0 所以可以成功
|
// 因为 num.a 低 1 位为 0 所以可以成功
|
||||||
assert.Equal(t, num, uint128be{0x0000000000000012 >> 1, 0x34567890abcdef12 >> 1})
|
assert.Equal(t, num, uint128be{0x0000000000000012 >> 1, 0x34567890abcdef12 >> 1})
|
||||||
num.shreq(7)
|
num.shreq(7)
|
||||||
|
|||||||
Reference in New Issue
Block a user