diff --git a/len.go b/len.go index 21f4746..cd33d9e 100644 --- a/len.go +++ b/len.go @@ -2,6 +2,8 @@ package unibase2n import "math/bits" +const powtab = "\x00\x04\x03\x00\x02\x00\x00\x00\x01" + // EncodeLen calculate encode length // offset will be appended as til+offset at last func (bs Base) EncodeLen(in int) (out, offset int) { @@ -9,7 +11,7 @@ func (bs Base) EncodeLen(in int) (out, offset int) { return 0, 0 } if bits.OnesCount8(bs.bit) == 1 { // 2的幂永无offset (1/2/4/8) - return in * (16 >> "\x00\x00\x01\x00\x02\x00\x00\x00\x03"[bs.bit]), 0 + return in << powtab[bs.bit], 0 } if bs.bit == 6 { // 特判 (6) 3*8=4*6 out = in / 3 * 4 * 2 @@ -52,3 +54,41 @@ func (bs Base) EncodeLen(in int) (out, offset int) { out += (remain/int(bs.bit) + 1 + 1) * 2 return } + +// DecodeLen calculate decode length +// offset must be legal or out will <= 0 +func (bs Base) DecodeLen(in, offset int) (out int) { + if in <= 0 || offset < 0 { + return 0 + } + if bits.OnesCount8(bs.bit) == 1 { // 2的幂永无offset (1/2/4/8) + return in >> powtab[bs.bit] + } + if bs.bit == 6 { // 特判 (6) 3*8=4*6 + if offset != 0 { + in -= (offset + 1) * 2 + } + return (in>>3)*3 + offset + } + if bs.bit < 8 { // (3/5/7) + if offset != 0 { + remain := offset * 8 + in -= (remain/int(bs.bit) + 1) * 2 + } + return (in>>4)*int(bs.bit) + offset + } + if bs.bit%2 == 0 { // bit 大于8且可被2整除 (10/12/14) + hb := int(bs.bit) >> 1 + if offset != 0 { + remain := offset * 8 + in -= (remain/int(bs.bit) + 1) * 2 + } + return (in>>4)*hb + offset + } + // (9/11/13/15) + if offset != 0 { + remain := offset * 8 + in -= (remain/int(bs.bit) + 1) * 2 + } + return (in>>5)*int(bs.bit) + offset +} diff --git a/len_test.go b/len_test.go new file mode 100644 index 0000000..ff3afd9 --- /dev/null +++ b/len_test.go @@ -0,0 +1,15 @@ +package unibase2n + +import "testing" + +func TestEnDecodeLen(t *testing.T) { + bs := Base{bit: 1} + for ; bs.bit < 16; bs.bit++ { + for i := 1; i <= 65536; i++ { + in := bs.DecodeLen(bs.EncodeLen(i)) + if i != in { + t.Fatal("bit:", bs.bit, "in:", i, "!= out:", in) + } + } + } +}