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
|
||||
|
||||
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
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) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
27
uint128be.go
27
uint128be.go
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user