mirror of
https://github.com/fumiama/unibase2n.git
synced 2026-06-05 00:32:47 +08:00
优化性能
This commit is contained in:
31
base.go
31
base.go
@@ -22,16 +22,29 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewBase generates a new base2n config
|
// NewBase generates a new base2n config
|
||||||
func NewBase(off, til uint16, bit uint8) (*Base, error) {
|
func NewBase(off, til uint16, bit uint8) (bs Base, err error) {
|
||||||
|
bs = Base{
|
||||||
|
off: off,
|
||||||
|
til: til,
|
||||||
|
bit: bit,
|
||||||
|
}
|
||||||
|
err = bs.check()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs Base) check() error {
|
||||||
|
off := bs.off
|
||||||
|
til := bs.til
|
||||||
|
bit := bs.bit
|
||||||
if off == 0 {
|
if off == 0 {
|
||||||
return nil, ErrZeroOffsetStart
|
return ErrZeroOffsetStart
|
||||||
}
|
}
|
||||||
if bit >= 16 || bit == 0 {
|
if bit >= 16 || bit == 0 {
|
||||||
return nil, ErrInvalidBitSize
|
return ErrInvalidBitSize
|
||||||
}
|
}
|
||||||
offe := uint32(off) + 1<<bit // [off, offe)
|
offe := uint32(off) + 1<<bit // [off, offe)
|
||||||
if offe > 0x10000 {
|
if offe > 0x10000 {
|
||||||
return nil, ErrOffsetOverflow
|
return ErrOffsetOverflow
|
||||||
}
|
}
|
||||||
tile := uint32(til) // [til, tile)
|
tile := uint32(til) // [til, tile)
|
||||||
if bit > 8 && bit%2 == 0 {
|
if bit > 8 && bit%2 == 0 {
|
||||||
@@ -40,14 +53,10 @@ func NewBase(off, til uint16, bit uint8) (*Base, error) {
|
|||||||
tile += uint32(bit)
|
tile += uint32(bit)
|
||||||
}
|
}
|
||||||
if tile > 0x10000 {
|
if tile > 0x10000 {
|
||||||
return nil, ErrTailOverflow
|
return ErrTailOverflow
|
||||||
}
|
}
|
||||||
if tile > uint32(off) && tile <= offe {
|
if tile > uint32(off) && tile <= offe {
|
||||||
return nil, ErrTailInCodingArea
|
return ErrTailInCodingArea
|
||||||
}
|
}
|
||||||
return &Base{
|
return nil
|
||||||
off: off,
|
|
||||||
til: til,
|
|
||||||
bit: bit,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
4
code.go
4
code.go
@@ -1,9 +1,9 @@
|
|||||||
package unibase2n
|
package unibase2n
|
||||||
|
|
||||||
func (bs *Base) Encode(data []byte) []byte {
|
func (bs Base) Encode(data []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) Decode(data []byte) []byte {
|
func (bs Base) Decode(data []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
12
conv.go
12
conv.go
@@ -16,7 +16,7 @@ func UTF82UTF16BE(b []byte) ([]byte, error) {
|
|||||||
return format.NewEncoder().Bytes(b)
|
return format.NewEncoder().Bytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) EncodeToString(b []byte) string {
|
func (bs Base) EncodeToString(b []byte) string {
|
||||||
out, err := UTF16BE2UTF8(bs.Encode(b))
|
out, err := UTF16BE2UTF8(bs.Encode(b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
@@ -24,11 +24,11 @@ func (bs *Base) EncodeToString(b []byte) string {
|
|||||||
return BytesToString(out)
|
return BytesToString(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) EncodeFromString(s string) []byte {
|
func (bs Base) EncodeFromString(s string) []byte {
|
||||||
return bs.Encode(StringToBytes(s))
|
return bs.Encode(StringToBytes(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) EncodeString(s string) string {
|
func (bs Base) EncodeString(s string) string {
|
||||||
out, err := UTF16BE2UTF8(bs.Encode(StringToBytes(s)))
|
out, err := UTF16BE2UTF8(bs.Encode(StringToBytes(s)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
@@ -36,11 +36,11 @@ func (bs *Base) EncodeString(s string) string {
|
|||||||
return BytesToString(out)
|
return BytesToString(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) DecodeToString(d []byte) string {
|
func (bs Base) DecodeToString(d []byte) string {
|
||||||
return BytesToString(bs.Decode(d))
|
return BytesToString(bs.Decode(d))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) DecodeFromString(s string) []byte {
|
func (bs Base) DecodeFromString(s string) []byte {
|
||||||
d, err := UTF82UTF16BE(StringToBytes(s))
|
d, err := UTF82UTF16BE(StringToBytes(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -48,7 +48,7 @@ func (bs *Base) DecodeFromString(s string) []byte {
|
|||||||
return bs.Decode(d)
|
return bs.Decode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *Base) DecodeString(s string) string {
|
func (bs Base) DecodeString(s string) string {
|
||||||
d, err := UTF82UTF16BE(StringToBytes(s))
|
d, err := UTF82UTF16BE(StringToBytes(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
25
define.go
Normal file
25
define.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package unibase2n
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Base16384 CJK Unified Ideographs
|
||||||
|
// see https://github.com/fumiama/base16384
|
||||||
|
Base16384, _ = NewBase(0x4e00, 0x3d00, 14)
|
||||||
|
// Base8192 谚文音節 Hangul Syllables
|
||||||
|
Base8192, _ = NewBase(0xac00, 0xcc00, 13)
|
||||||
|
// Base256 谚文字母 Hangul Jamo
|
||||||
|
Base256, _ = NewBase(0x1100, 0, 8)
|
||||||
|
// BaseMath (256) 數學運算符 Mathematical Operators
|
||||||
|
BaseMath, _ = NewBase(0x2200, 0, 8)
|
||||||
|
// Base128 帶圈或括號的字母數字 Enclosed Alphanumerics
|
||||||
|
Base128, _ = NewBase(0x2460, 0x24f4, 7)
|
||||||
|
// Base64 箭頭 Arrows
|
||||||
|
Base64, _ = NewBase(0x2190, 0x21d0, 6)
|
||||||
|
// Base64Gua 六十四卦 YiJing Hexagram Symbols
|
||||||
|
Base64Gua, _ = NewBase(0x3400, 0x262f, 6)
|
||||||
|
// Base32 方塊元素 Block Elements
|
||||||
|
Base32, _ = NewBase(0x2580, 0x259f, 5)
|
||||||
|
// Base16 漢文訓讀點 Kanbun Kundoku Den
|
||||||
|
Base16, _ = NewBase(0x3190, 0, 4)
|
||||||
|
// Base8 八卦 YiJing Hexagram Symbols
|
||||||
|
Base8, _ = NewBase(0x2630, 0x2689, 3)
|
||||||
|
)
|
||||||
67
pack.go
67
pack.go
@@ -2,67 +2,44 @@ package unibase2n
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pack uint64
|
type Pack uint64
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Base16384 CJK Unified Ideographs
|
ErrInvalidPack = errors.New("invalid pack")
|
||||||
// see https://github.com/fumiama/base16384
|
|
||||||
Base16384 = newbasepack(0x4e00, 0x3d00, 14)
|
|
||||||
// Base8192 谚文音節 Hangul Syllables
|
|
||||||
Base8192 = newbasepack(0xac00, 0xcc00, 13)
|
|
||||||
// Base256 谚文字母 Hangul Jamo
|
|
||||||
Base256 = newbasepack(0x1100, 0, 8)
|
|
||||||
// BaseMath (256) 數學運算符 Mathematical Operators
|
|
||||||
BaseMath = newbasepack(0x2200, 0, 8)
|
|
||||||
// Base128 帶圈或括號的字母數字 Enclosed Alphanumerics
|
|
||||||
Base128 = newbasepack(0x2460, 0x24f4, 7)
|
|
||||||
// Base64 箭頭 Arrows
|
|
||||||
Base64 = newbasepack(0x2190, 0x21d0, 6)
|
|
||||||
// Base64Gua 六十四卦 YiJing Hexagram Symbols
|
|
||||||
Base64Gua = newbasepack(0x3400, 0x262f, 6)
|
|
||||||
// Base32 方塊元素 Block Elements
|
|
||||||
Base32 = newbasepack(0x2580, 0x259f, 5)
|
|
||||||
// Base16 漢文訓讀點 Kanbun Kundoku Den
|
|
||||||
Base16 = newbasepack(0x3190, 0, 4)
|
|
||||||
// Base8 八卦 YiJing Hexagram Symbols
|
|
||||||
Base8 = newbasepack(0x2630, 0x2689, 3)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newbasepack(off, til uint16, bit uint8) Pack {
|
|
||||||
b, err := NewBase(off, til, bit)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return b.Pack()
|
|
||||||
}
|
|
||||||
|
|
||||||
// New base2n from a packed config
|
// New base2n from a packed config
|
||||||
func New(pack Pack) *Base {
|
func New(pack Pack) (bs Base, err error) {
|
||||||
b := &Base{}
|
if pack&0xff == 0 && pack&0xff000000_00000000 == 0 {
|
||||||
|
err = ErrInvalidPack
|
||||||
|
return
|
||||||
|
}
|
||||||
ismele := isLittleEndian()
|
ismele := isLittleEndian()
|
||||||
isitle := pack&0xffffff != 0
|
isitle := pack&0xffffff != 0
|
||||||
if ismele == isitle { // same endian
|
if ismele == isitle { // same endian
|
||||||
*(*Pack)(unsafe.Pointer(b)) = pack
|
*(*Pack)(unsafe.Pointer(&bs)) = pack
|
||||||
return b
|
} else {
|
||||||
|
field := (*[8]byte)(unsafe.Pointer(&pack))
|
||||||
|
if isitle { // packed in little endian but I am big
|
||||||
|
bs.off = binary.BigEndian.Uint16(field[6:8])
|
||||||
|
bs.til = binary.BigEndian.Uint16(field[4:6])
|
||||||
|
} else { // packed in big endian but I am little
|
||||||
|
bs.off = binary.LittleEndian.Uint16(field[6:8])
|
||||||
|
bs.til = binary.LittleEndian.Uint16(field[4:6])
|
||||||
|
}
|
||||||
|
bs.bit = field[3]
|
||||||
}
|
}
|
||||||
field := (*[8]byte)(unsafe.Pointer(&pack))
|
err = bs.check()
|
||||||
if isitle { // packed in little endian but I am big
|
return
|
||||||
b.off = binary.BigEndian.Uint16(field[6:8])
|
|
||||||
b.til = binary.BigEndian.Uint16(field[4:6])
|
|
||||||
} else { // packed in big endian but I am little
|
|
||||||
b.off = binary.LittleEndian.Uint16(field[6:8])
|
|
||||||
b.til = binary.LittleEndian.Uint16(field[4:6])
|
|
||||||
}
|
|
||||||
b.bit = field[3]
|
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack this config into an integer
|
// Pack this config into an integer
|
||||||
func (bs *Base) Pack() Pack {
|
func (bs Base) Pack() Pack {
|
||||||
return *(*Pack)(unsafe.Pointer(bs))
|
return *(*Pack)(unsafe.Pointer(&bs))
|
||||||
}
|
}
|
||||||
|
|
||||||
func isLittleEndian() bool {
|
func isLittleEndian() bool {
|
||||||
|
|||||||
15
pack_test.go
15
pack_test.go
@@ -12,15 +12,24 @@ func TestPackUnpack(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
p := bs.Pack()
|
p := bs.Pack()
|
||||||
bs1 := New(p)
|
bs1, err := New(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
assert.Equal(t, bs, bs1)
|
assert.Equal(t, bs, bs1)
|
||||||
ismele := isLittleEndian()
|
ismele := isLittleEndian()
|
||||||
if ismele {
|
if ismele {
|
||||||
// simulate be pack -> le unpack
|
// simulate be pack -> le unpack
|
||||||
bs2 := New(0x1234567808000000)
|
bs2, err := New(0x1234567808000000)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
assert.Equal(t, bs, bs2)
|
assert.Equal(t, bs, bs2)
|
||||||
} else { // simulate le pack -> be unpack
|
} else { // simulate le pack -> be unpack
|
||||||
bs2 := New(0x0000000878563412)
|
bs2, err := New(0x0000000878563412)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
assert.Equal(t, bs, bs2)
|
assert.Equal(t, bs, bs2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
uint128be.go
Normal file
6
uint128be.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package unibase2n
|
||||||
|
|
||||||
|
type usgnint128 struct {
|
||||||
|
a uint64
|
||||||
|
b uint64
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user