1
0
mirror of https://github.com/fumiama/unibase2n.git synced 2026-06-05 00:32:47 +08:00

finish dec128blk1

This commit is contained in:
源文雨
2022-10-01 15:30:15 +08:00
parent 08228b7a61
commit aff58aa75e
5 changed files with 113 additions and 3 deletions

View File

@@ -1,5 +1,63 @@
package unibase2n
import (
"encoding/binary"
)
func (bs Base) Decode(data []byte) []byte {
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
View 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)
}

View File

@@ -57,7 +57,7 @@ func enc16blk1(mask uint16, in, out []byte) {
func enc64blk2(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)) & 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)
}
}
@@ -67,7 +67,7 @@ func enc64blk2(mask uint64, in, out []byte) {
func enc32blk4(mask uint32, in, out []byte) {
for i, n := range in {
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)
}
}

View File

@@ -12,6 +12,11 @@ type uint128be struct {
b uint64
}
var (
u128minusone = uint128be{0xffffffff_ffffffff, 0xffffffff_ffffffff}
u128one = uint128be{0, 1}
)
func readuint128be(b []byte) uint128be {
if len(b) < 16 {
b = append(b, make([]byte, 16-len(b))...)
@@ -29,6 +34,20 @@ func (num *uint128be) addeq(n uint128be) {
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
func (num *uint128be) shreq(c uint8) {
mask := uint64(1)<<c - 1
@@ -37,6 +56,14 @@ func (num *uint128be) shreq(c uint8) {
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) {
num.a &= n.a
num.b &= n.b

View File

@@ -11,6 +11,7 @@ func TestUint128be(t *testing.T) {
zero := readuint128be(make([]byte, 16))
one := readuint128be([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
num := readuint128be(buf[:])
assert.Equal(t, zero.sub(one), num)
num.addeq(one)
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}))
@@ -22,7 +23,9 @@ func TestUint128be(t *testing.T) {
num.shreq(32)
assert.Equal(t, num, uint128be{0x0000000000000012, 0x34567890abcdef12})
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 所以可以成功
assert.Equal(t, num, uint128be{0x0000000000000012 >> 1, 0x34567890abcdef12 >> 1})
num.shreq(7)