diff --git a/base14.go b/base14.go new file mode 100644 index 0000000..cc9cca5 --- /dev/null +++ b/base14.go @@ -0,0 +1,153 @@ +// +build amd64 arm64 ppc64le mips64le 386 arm mipsle + +// Package base14 base16384 的 go 接口 +package base14 + +import ( + "unsafe" + + "github.com/wdvxdr1123/ZeroBot/utils/helper" +) + +func EncodeString(s string) []byte { + return Encode(helper.StringToBytes(s)) +} + +func DecodeString(s string) []byte { + return Decode(helper.StringToBytes(s)) +} + +func Encode(b []byte) (encd []byte) { + outlen := len(b) / 7 * 8 + offset := len(b) % 7 + switch offset { //算上偏移标志字符占用的2字节 + case 0: + break + case 1: + outlen += 4 + case 2, 3: + outlen += 6 + case 4, 5: + outlen += 8 + case 6: + outlen += 10 + } + encd = make([]byte, outlen, outlen+8) //冗余的8B用于可能的结尾的覆盖 + vals := (*slice)(unsafe.Pointer(&encd)).Data + var n uintptr + i := 0 + for ; i <= len(b)-7; i += 7 { + sum := 0x000000000000003f & ((uint64)(b[i]) >> 2) + sum |= (((uint64)(b[i+1]) << 6) | ((uint64)(b[i]) << 14)) & 0x000000000000ff00 + sum |= (((uint64)(b[i+1]) << 20) | ((uint64)(b[i+2]) << 12)) & 0x00000000003f0000 + sum |= (((uint64)(b[i+2]) << 28) | ((uint64)(b[i+3]) << 20)) & 0x00000000ff000000 + sum |= (((uint64)(b[i+3]) << 34) | ((uint64)(b[i+4]) << 26)) & 0x0000003f00000000 + sum |= (((uint64)(b[i+4]) << 42) | ((uint64)(b[i+5]) << 34)) & 0x0000ff0000000000 + sum |= ((uint64)(b[i+5]) << 48) & 0x003f000000000000 + sum |= ((uint64)(b[i+6]) << 56) & 0xff00000000000000 + sum += 0x004e004e004e004e + *(*uint64)(unsafe.Pointer(uintptr(vals) + n)) = sum + n += 8 + } + if offset > 0 { + sum := 0x000000000000003f & ((uint64)(b[i]) >> 2) + sum |= ((uint64)(b[i]) << 14) & 0x000000000000c000 + if offset > 1 { + sum |= ((uint64)(b[i+1]) << 6) & 0x0000000000003f00 + sum |= ((uint64)(b[i+1]) << 20) & 0x0000000000300000 + if offset > 2 { + sum |= ((uint64)(b[i+2]) << 12) & 0x00000000000f0000 + sum |= ((uint64)(b[i+2]) << 28) & 0x00000000f0000000 + if offset > 3 { + sum |= ((uint64)(b[i+3]) << 20) & 0x000000000f000000 + sum |= ((uint64)(b[i+3]) << 34) & 0x0000003c00000000 + if offset > 4 { + sum |= ((uint64)(b[i+4]) << 26) & 0x0000000300000000 + sum |= ((uint64)(b[i+4]) << 42) & 0x0000fc0000000000 + if offset > 5 { + sum |= ((uint64)(b[i+5]) << 34) & 0x0000030000000000 + sum |= ((uint64)(b[i+5]) << 48) & 0x003f000000000000 + } + } + } + } + } + sum += 0x004e004e004e004e + *(*uint64)(unsafe.Pointer(uintptr(vals) + n)) = sum + encd[outlen-2] = '=' + encd[outlen-1] = byte(offset) + } + return +} + +func Decode(b []byte) (decd []byte) { + outlen := len(b) + offset := 0 + if b[len(b)-2] == '=' { + offset = int(b[len(b)-1]) + switch offset { //算上偏移标志字符占用的2字节 + case 0: + break + case 1: + outlen -= 4 + case 2, 3: + outlen -= 6 + case 4, 5: + outlen -= 8 + case 6: + outlen -= 10 + } + } + outlen = outlen/8*7 + offset + decd = make([]byte, outlen) + vals := (*slice)(unsafe.Pointer(&b)).Data + var n uintptr + i := 0 + for ; i <= len(decd)-7; n += 8 { + sum := *(*uint64)(unsafe.Pointer(uintptr(vals) + n)) - 0x004e004e004e004e + decd[i] = byte(((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14)) + i++ + decd[i] = byte(((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20)) + i++ + decd[i] = byte(((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28)) + i++ + decd[i] = byte(((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34)) + i++ + decd[i] = byte(((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42)) + i++ + decd[i] = byte(((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48)) + i++ + decd[i] = byte(((sum & 0xff00000000000000) >> 56)) + i++ + } + if offset > 0 { + sum := *(*uint64)(unsafe.Pointer(uintptr(vals) + n)) - 0x000000000000004e + decd[i] = byte(((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14)) + i++ + if offset > 1 { + sum -= 0x00000000004e0000 + decd[i] = byte(((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20)) + i++ + if offset > 2 { + decd[i] = byte(((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28)) + i++ + if offset > 3 { + sum -= 0x0000004e00000000 + decd[i] = byte(((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34)) + i++ + if offset > 4 { + decd[i] = byte(((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42)) + i++ + if offset > 5 { + sum -= 0x004e000000000000 + decd[i] = byte(((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48)) + i++ + } + + } + } + } + } + } + return +} diff --git a/base1432.go b/base1432.go deleted file mode 100644 index 205e895..0000000 --- a/base1432.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build 386 arm - -// Package base14 base16384 的 go 接口 -package base14 - -// #cgo CFLAGS: -I/usr/local/include -// #cgo LDFLAGS: -L/usr/local/lib -lbase14 -// #include -// #include -import "C" -import ( - "unsafe" -) - -func Encode(b []byte) []byte { - ld := C.encode((*C.uchar)(unsafe.Pointer(&b[0])), (uint)(len(b))) - ldlen := uintptr(ld.len) - // []byte 的数据结构 - e := [3]uintptr{uintptr(unsafe.Pointer(ld.data)), ldlen, ldlen} - return *(*[]byte)(unsafe.Pointer(&e)) -} - -func Decode(b []byte) []byte { - ld := C.decode((*C.uchar)(unsafe.Pointer(&b[0])), (uint)(len(b))) - ldlen := uintptr(ld.len) - // []byte 的数据结构 - e := [3]uintptr{uintptr(unsafe.Pointer(ld.data)), ldlen, ldlen} - return *(*[]byte)(unsafe.Pointer(&e)) -} diff --git a/base1464.go b/base1464.go deleted file mode 100644 index 3ff1f8f..0000000 --- a/base1464.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build amd64 arm64 - -// Package base14 base16384 的 go 接口 -package base14 - -// #cgo CFLAGS: -I/usr/local/include -// #cgo LDFLAGS: -L/usr/local/lib -lbase14 -// #include -// #include -import "C" -import ( - "unsafe" -) - -func Encode(b []byte) []byte { - ld := C.encode((*C.uchar)(unsafe.Pointer(&b[0])), (C.ulong)(len(b))) - ldlen := uintptr(ld.len) - // []byte 的数据结构 - e := [3]uintptr{uintptr(unsafe.Pointer(ld.data)), ldlen, ldlen} - return *(*[]byte)(unsafe.Pointer(&e)) -} - -func Decode(b []byte) []byte { - ld := C.decode((*C.uchar)(unsafe.Pointer(&b[0])), (C.ulong)(len(b))) - ldlen := uintptr(ld.len) - // []byte 的数据结构 - e := [3]uintptr{uintptr(unsafe.Pointer(ld.data)), ldlen, ldlen} - return *(*[]byte)(unsafe.Pointer(&e)) -} diff --git a/base14_test.go b/base14_test.go new file mode 100644 index 0000000..ad80ad3 --- /dev/null +++ b/base14_test.go @@ -0,0 +1,30 @@ +package base14 + +import ( + "testing" +) + +func TestBase14(t *testing.T) { + teststr := "一个测试293大大的啊定位为恶的我284的我……#@%@%@" + e := EncodeString(teststr) + es, err := UTF16be2utf8(e) + if err == nil { + t.Log(string(es)) + d, err := UTF82utf16be(es) + if string(d) == string(e) { + if err == nil { + ds := string(Decode(d)) + t.Log(ds) + if ds != teststr { + t.Fail() + } + } else { + t.Fatal(err) + } + } else { + t.Fatal(d) + } + } else { + t.Fatal(err) + } +} diff --git a/base14stub.go b/base14stub.go new file mode 100644 index 0000000..96a9edf --- /dev/null +++ b/base14stub.go @@ -0,0 +1,19 @@ +// +build !386,!arm,!mipsle,!amd64,!arm64,!ppc64le,!mips64le + +package base14 + +func EncodeString(s string) []byte { + return []byte{"stub!"} +} + +func DecodeString(s string) []byte { + return []byte{"stub!"} +} + +func Encode(b []byte) []byte { + return []byte{"stub!"} +} + +func Decode(b []byte) []byte { + return []byte{"stub!"} +} diff --git a/go.mod b/go.mod index 8d5766a..57b53d2 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/fumiama/go-base16384 go 1.16 -require golang.org/x/text v0.3.6 +require ( + github.com/wdvxdr1123/ZeroBot v1.3.2 + golang.org/x/text v0.3.6 +) diff --git a/go.sum b/go.sum index 3c12b4f..974fffb 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,39 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA= +github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= +github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/wdvxdr1123/ZeroBot v1.3.2 h1:EFZNb3awNbwxRtmDkWv3PH6Z9rUV6ZLFa3hBmRMRRCA= +github.com/wdvxdr1123/ZeroBot v1.3.2/go.mod h1:i2DIqQjtjE+3gvVi9r9sc+QpNaUuyTXx/HNXXayIpwI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/mem.go b/mem.go deleted file mode 100644 index 896add9..0000000 --- a/mem.go +++ /dev/null @@ -1,10 +0,0 @@ -package base14 - -// #include -import "C" -import "unsafe" - -// Free memory allocated by encode / decode -func Free(b []byte) { - C.free(unsafe.Pointer(&b[0])) -} diff --git a/slice.go b/slice.go new file mode 100644 index 0000000..b133217 --- /dev/null +++ b/slice.go @@ -0,0 +1,15 @@ +package base14 + +import "unsafe" + +// slice is the runtime representation of a slice. +// It cannot be used safely or portably and its representation may +// change in a later release. +// +// Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the +// data it references will not be garbage collected. +type slice struct { + Data unsafe.Pointer + Len int + Cap int +}