mirror of
https://github.com/fumiama/go-base16384.git
synced 2026-06-12 22:40:42 +08:00
add amd64 asm
name old time/op new time/op delta EncodeTo/16-8 45.5ns ± 1% 35.9ns ± 1% -21.01% (p=0.008 n=5+5) EncodeTo/256-8 241ns ± 1% 170ns ± 1% -29.64% (p=0.008 n=5+5) EncodeTo/4K-8 2.90µs ± 0% 1.70µs ± 0% -41.60% (p=0.008 n=5+5) EncodeTo/32K-8 23.5µs ± 2% 13.6µs ± 2% -42.20% (p=0.008 n=5+5) DecodeTo/16-8 20.2ns ± 0% 10.3ns ± 2% -48.92% (p=0.008 n=5+5) DecodeTo/256-8 141ns ± 1% 71ns ± 0% -49.55% (p=0.008 n=5+5) DecodeTo/4K-8 2.03µs ± 1% 0.94µs ± 0% -53.82% (p=0.008 n=5+5) DecodeTo/32K-8 16.1µs ± 0% 7.5µs ± 0% -53.22% (p=0.008 n=5+5) name old speed new speed delta EncodeTo/16-8 352MB/s ± 1% 445MB/s ± 1% +26.59% (p=0.008 n=5+5) EncodeTo/256-8 1.06GB/s ± 1% 1.51GB/s ± 1% +42.13% (p=0.008 n=5+5) EncodeTo/4K-8 1.41GB/s ± 0% 2.42GB/s ± 0% +71.24% (p=0.008 n=5+5) EncodeTo/32K-8 1.40GB/s ± 2% 2.42GB/s ± 2% +73.01% (p=0.008 n=5+5) DecodeTo/16-8 1.09GB/s ± 0% 2.14GB/s ± 2% +95.84% (p=0.008 n=5+5) DecodeTo/256-8 2.10GB/s ± 1% 4.16GB/s ± 0% +98.21% (p=0.008 n=5+5) DecodeTo/4K-8 2.30GB/s ± 1% 4.99GB/s ± 0% +116.55% (p=0.008 n=5+5) DecodeTo/32K-8 2.33GB/s ± 0% 4.98GB/s ± 0% +113.78% (p=0.008 n=5+5)
This commit is contained in:
193
base14.go
193
base14.go
@@ -2,10 +2,10 @@
|
|||||||
package base14
|
package base14
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func EncodeLen(in int) (out int) {
|
func EncodeLen(in int) (out int) {
|
||||||
out = in / 7 * 8
|
out = in / 7 * 8
|
||||||
offset := in % 7
|
offset := in % 7
|
||||||
@@ -40,53 +40,7 @@ func Encode(b []byte) (encd []byte) {
|
|||||||
outlen += 10
|
outlen += 10
|
||||||
}
|
}
|
||||||
encd = make([]byte, outlen)
|
encd = make([]byte, outlen)
|
||||||
var n int
|
encode(offset, outlen, append(b, 0), encd)
|
||||||
i := 0
|
|
||||||
b = append(b, 0)
|
|
||||||
for ; i <= len(b)-7; i += 7 {
|
|
||||||
shift := binary.BigEndian.Uint64(b[i:]) >> 2
|
|
||||||
sum := shift
|
|
||||||
sum &= 0x3fff000000000000
|
|
||||||
shift >>= 2
|
|
||||||
sum |= shift & 0x00003fff00000000
|
|
||||||
shift >>= 2
|
|
||||||
sum |= shift & 0x000000003fff0000
|
|
||||||
shift >>= 2
|
|
||||||
sum |= shift & 0x0000000000003fff
|
|
||||||
sum += 0x4e004e004e004e00
|
|
||||||
binary.BigEndian.PutUint64(encd[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
|
|
||||||
var tmp [8]byte
|
|
||||||
binary.LittleEndian.PutUint64(tmp[:], sum)
|
|
||||||
copy(encd[n:], tmp[:])
|
|
||||||
encd[outlen-2] = '='
|
|
||||||
encd[outlen-1] = byte(offset)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,56 +62,11 @@ func EncodeTo(b, encd []byte) error {
|
|||||||
if len(encd) < outlen {
|
if len(encd) < outlen {
|
||||||
return errors.New("encd too small")
|
return errors.New("encd too small")
|
||||||
}
|
}
|
||||||
var n int
|
encode(offset, outlen, append(b, 0), encd)
|
||||||
i := 0
|
|
||||||
b = append(b, 0)
|
|
||||||
for ; i <= len(b)-7; i += 7 {
|
|
||||||
shift := binary.BigEndian.Uint64(b[i:]) >> 2
|
|
||||||
sum := shift
|
|
||||||
sum &= 0x3fff000000000000
|
|
||||||
shift >>= 2
|
|
||||||
sum |= shift & 0x00003fff00000000
|
|
||||||
shift >>= 2
|
|
||||||
sum |= shift & 0x000000003fff0000
|
|
||||||
shift >>= 2
|
|
||||||
sum |= shift & 0x0000000000003fff
|
|
||||||
sum += 0x4e004e004e004e00
|
|
||||||
binary.BigEndian.PutUint64(encd[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
|
|
||||||
var tmp [8]byte
|
|
||||||
binary.LittleEndian.PutUint64(tmp[:], sum)
|
|
||||||
copy(encd[n:], tmp[:])
|
|
||||||
encd[outlen-2] = '='
|
|
||||||
encd[outlen-1] = byte(offset)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func DecodeLen(in, offset int) (out int) {
|
func DecodeLen(in, offset int) (out int) {
|
||||||
out = in
|
out = in
|
||||||
switch offset { //算上偏移标志字符占用的2字节
|
switch offset { //算上偏移标志字符占用的2字节
|
||||||
@@ -176,6 +85,7 @@ func DecodeLen(in, offset int) (out int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func Decode(b []byte) (decd []byte) {
|
func Decode(b []byte) (decd []byte) {
|
||||||
outlen := len(b)
|
outlen := len(b)
|
||||||
offset := 0
|
offset := 0
|
||||||
@@ -196,54 +106,11 @@ func Decode(b []byte) (decd []byte) {
|
|||||||
}
|
}
|
||||||
outlen = outlen/8*7 + offset
|
outlen = outlen/8*7 + offset
|
||||||
decd = make([]byte, outlen)
|
decd = make([]byte, outlen)
|
||||||
var n uintptr
|
decode(offset, outlen, b, decd)
|
||||||
i := 0
|
|
||||||
for ; i <= outlen-7; n += 8 {
|
|
||||||
shift := binary.BigEndian.Uint64(b[n:]) - 0x4e004e004e004e00
|
|
||||||
shift <<= 2
|
|
||||||
sum := shift & 0xfffc000000000000
|
|
||||||
shift <<= 2
|
|
||||||
sum |= shift & 0x0003fff000000000
|
|
||||||
shift <<= 2
|
|
||||||
sum |= shift & 0x0000000fffc00000
|
|
||||||
shift <<= 2
|
|
||||||
sum |= shift & 0x00000000003fff00
|
|
||||||
binary.BigEndian.PutUint64(decd[i:], sum)
|
|
||||||
i += 7
|
|
||||||
}
|
|
||||||
if offset > 0 {
|
|
||||||
var tmp [8]byte
|
|
||||||
copy(tmp[:], b[n:])
|
|
||||||
sum := binary.LittleEndian.Uint64(tmp[:]) - 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
func DecodeTo(b []byte, decd []byte) error {
|
func DecodeTo(b []byte, decd []byte) error {
|
||||||
outlen := len(b)
|
outlen := len(b)
|
||||||
offset := 0
|
offset := 0
|
||||||
@@ -266,50 +133,6 @@ func DecodeTo(b []byte, decd []byte) error {
|
|||||||
if len(decd) < outlen {
|
if len(decd) < outlen {
|
||||||
return errors.New("decd too small")
|
return errors.New("decd too small")
|
||||||
}
|
}
|
||||||
var n uintptr
|
decode(offset, outlen, b, decd)
|
||||||
i := 0
|
|
||||||
for ; i <= outlen-7; n += 8 {
|
|
||||||
shift := binary.BigEndian.Uint64(b[n:]) - 0x4e004e004e004e00
|
|
||||||
shift <<= 2
|
|
||||||
sum := shift & 0xfffc000000000000
|
|
||||||
shift <<= 2
|
|
||||||
sum |= shift & 0x0003fff000000000
|
|
||||||
shift <<= 2
|
|
||||||
sum |= shift & 0x0000000fffc00000
|
|
||||||
shift <<= 2
|
|
||||||
sum |= shift & 0x00000000003fff00
|
|
||||||
binary.BigEndian.PutUint64(decd[i:], sum)
|
|
||||||
i += 7
|
|
||||||
}
|
|
||||||
if offset > 0 {
|
|
||||||
var tmp [8]byte
|
|
||||||
copy(tmp[:], b[n:])
|
|
||||||
sum := binary.LittleEndian.Uint64(tmp[:]) - 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 nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
235
base14_amd64.s
Normal file
235
base14_amd64.s
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func encode(offset, outlen int, b, encd []byte)
|
||||||
|
TEXT ·encode(SB), NOSPLIT, $56-64
|
||||||
|
MOVQ ·offset+0(FP), R10
|
||||||
|
MOVQ ·outlen+8(FP), AX
|
||||||
|
MOVQ ·data+16(FP), DI
|
||||||
|
MOVQ ·dlen+24(FP), R8
|
||||||
|
MOVQ ·encd+40(FP), R9
|
||||||
|
XORQ CX, CX
|
||||||
|
XORQ SI, SI
|
||||||
|
SUBQ $6, R8
|
||||||
|
JLE encrem
|
||||||
|
MOVQ $4611404543450677248, BP
|
||||||
|
MOVQ $70364449210368, BX
|
||||||
|
MOVQ $5620578098173988352, R11
|
||||||
|
|
||||||
|
enclop:
|
||||||
|
MOVBEQ (DI)(CX*1), DX
|
||||||
|
INCQ SI
|
||||||
|
ADDQ $7, CX
|
||||||
|
MOVQ DX, R13
|
||||||
|
MOVQ DX, R12
|
||||||
|
SHRQ $2, R13
|
||||||
|
SHRQ $4, R12
|
||||||
|
ANDQ BX, R12
|
||||||
|
ANDQ BP, R13
|
||||||
|
ORQ R12, R13
|
||||||
|
MOVQ DX, R12
|
||||||
|
SHRQ $8, DX
|
||||||
|
SHRQ $6, R12
|
||||||
|
ANDL $16383, DX
|
||||||
|
ANDL $1073676288, R12
|
||||||
|
ORQ R13, R12
|
||||||
|
ORQ R12, DX
|
||||||
|
ADDQ R11, DX
|
||||||
|
MOVBEQ DX, -8(R9)(SI*8)
|
||||||
|
CMPQ CX, R8
|
||||||
|
JL enclop
|
||||||
|
|
||||||
|
encrem:
|
||||||
|
TESTQ R10, R10
|
||||||
|
JE encend
|
||||||
|
|
||||||
|
MOVBLZX (DI)(CX*1), DX
|
||||||
|
MOVL DX, R8
|
||||||
|
SALQ $14, DX
|
||||||
|
SHRB $2, R8
|
||||||
|
ANDL $49152, DX
|
||||||
|
MOVBLZX R8, R8
|
||||||
|
ORQ R8, DX
|
||||||
|
CMPL R10, $1
|
||||||
|
JE encsav
|
||||||
|
|
||||||
|
MOVBQSX 1(DI)(CX*1), R8
|
||||||
|
MOVQ R8, R11
|
||||||
|
SALQ $20, R8
|
||||||
|
SALQ $6, R11
|
||||||
|
ANDL $3145728, R8
|
||||||
|
ANDL $16128, R11
|
||||||
|
ORQ R11, DX
|
||||||
|
ORQ R8, DX
|
||||||
|
CMPL R10, $2
|
||||||
|
JE encsav
|
||||||
|
|
||||||
|
MOVBQSX 2(DI)(CX*1), R8
|
||||||
|
MOVQ R8, R11
|
||||||
|
SALQ $28, R8
|
||||||
|
SALQ $12, R11
|
||||||
|
MOVL R8, R8
|
||||||
|
ANDL $983040, R11
|
||||||
|
ORQ R11, R8
|
||||||
|
ORQ R8, DX
|
||||||
|
CMPL R10, $3
|
||||||
|
JE encsav
|
||||||
|
|
||||||
|
MOVQ $257698037760, BX
|
||||||
|
MOVBQSX 3(DI)(CX*1), R8
|
||||||
|
MOVQ R8, R11
|
||||||
|
SALQ $34, R8
|
||||||
|
SALQ $20, R11
|
||||||
|
ANDQ BX, R8
|
||||||
|
ANDL $251658240, R11
|
||||||
|
ORQ R11, R8
|
||||||
|
ORQ R8, DX
|
||||||
|
CMPL R10, $4
|
||||||
|
JE encsav
|
||||||
|
|
||||||
|
MOVQ $12884901888, BX
|
||||||
|
MOVBQSX 4(DI)(CX*1), R8
|
||||||
|
MOVQ R8, R11
|
||||||
|
SALQ $42, R8
|
||||||
|
SALQ $26, R11
|
||||||
|
ANDQ BX, R11
|
||||||
|
MOVQ $277076930199552, BX
|
||||||
|
ANDQ BX, R8
|
||||||
|
ORQ R11, R8
|
||||||
|
ORQ R8, DX
|
||||||
|
CMPL R10, $5
|
||||||
|
JE encsav
|
||||||
|
|
||||||
|
MOVQ $3298534883328, R8
|
||||||
|
MOVBQSX 5(DI)(CX*1), CX
|
||||||
|
MOVQ CX, DI
|
||||||
|
SALQ $48, CX
|
||||||
|
SALQ $34, DI
|
||||||
|
ANDQ R8, DI
|
||||||
|
MOVQ $17732923532771328, R8
|
||||||
|
ANDQ R8, CX
|
||||||
|
ORQ DI, CX
|
||||||
|
ORQ CX, DX
|
||||||
|
|
||||||
|
encsav:
|
||||||
|
MOVQ $21955383195992142, CX
|
||||||
|
ADDQ CX, DX
|
||||||
|
MOVQ DX, 0(R9)(SI*8)
|
||||||
|
MOVB $61, -2(R9)(AX*1)
|
||||||
|
MOVB R10, -1(R9)(AX*1)
|
||||||
|
|
||||||
|
encend:
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
// func decode(offset, outlen int, b, decd []byte)
|
||||||
|
TEXT ·decode(SB), NOSPLIT, $56-64
|
||||||
|
MOVQ ·offset+0(FP), BX
|
||||||
|
MOVQ ·outlen+8(FP), R8
|
||||||
|
MOVQ ·data+16(FP), DI
|
||||||
|
MOVQ ·decd+40(FP), R9
|
||||||
|
XORQ CX, CX
|
||||||
|
XORQ SI, SI
|
||||||
|
SUBQ $6, R8
|
||||||
|
JLE decrem
|
||||||
|
MOVQ $-5620578098173988352, R12
|
||||||
|
MOVQ $-1125899906842624, BP
|
||||||
|
MOVQ $1125831187365888, R11
|
||||||
|
MOVQ $68715282432, R10
|
||||||
|
|
||||||
|
declop:
|
||||||
|
MOVBEQ (DI)(SI*8), DX
|
||||||
|
INCQ SI
|
||||||
|
ADDQ R12, DX
|
||||||
|
MOVQ DX, R13
|
||||||
|
LEAQ 0(DX*4), R14
|
||||||
|
SALQ $4, R13
|
||||||
|
ANDQ BP, R14
|
||||||
|
ANDQ R11, R13
|
||||||
|
ORQ R13, R14
|
||||||
|
MOVQ DX, R13
|
||||||
|
SALQ $8, DX
|
||||||
|
SALQ $6, R13
|
||||||
|
ANDL $4194048, DX
|
||||||
|
ANDQ R10, R13
|
||||||
|
ORQ R14, R13
|
||||||
|
ORQ R13, DX
|
||||||
|
MOVBEQ DX, (R9)(CX*1)
|
||||||
|
ADDQ $7, CX
|
||||||
|
CMPQ CX, R8
|
||||||
|
JL declop
|
||||||
|
|
||||||
|
decrem:
|
||||||
|
TESTQ BX, BX
|
||||||
|
JE decend
|
||||||
|
|
||||||
|
MOVQ (DI)(SI*8), DI
|
||||||
|
LEAQ -78(DI), SI
|
||||||
|
MOVQ SI, DX
|
||||||
|
SALL $2, SI
|
||||||
|
SHRQ $14, DX
|
||||||
|
ANDL $3, DX
|
||||||
|
ORL SI, DX
|
||||||
|
MOVB DX, 0(R9)(CX*1)
|
||||||
|
CMPL BX, $1
|
||||||
|
JE decend
|
||||||
|
|
||||||
|
LEAQ -5111886(DI), DX
|
||||||
|
MOVQ DX, SI
|
||||||
|
MOVQ DX, R8
|
||||||
|
SHRQ $6, SI
|
||||||
|
SHRQ $20, R8
|
||||||
|
ANDL $-4, SI
|
||||||
|
ANDL $3, R8
|
||||||
|
ORL R8, SI
|
||||||
|
MOVB SI, 1(R9)(CX*1)
|
||||||
|
CMPL BX, $2
|
||||||
|
JE decend
|
||||||
|
|
||||||
|
MOVQ DX, SI
|
||||||
|
SHRQ $28, DX
|
||||||
|
SHRQ $12, SI
|
||||||
|
ANDL $15, DX
|
||||||
|
ANDL $-16, SI
|
||||||
|
ORL SI, DX
|
||||||
|
MOVB DX, 2(R9)(CX*1)
|
||||||
|
CMPL BX, $3
|
||||||
|
JE decend
|
||||||
|
|
||||||
|
MOVQ $-335012560974, DX
|
||||||
|
ADDQ DI, DX
|
||||||
|
MOVQ DX, SI
|
||||||
|
MOVQ DX, R8
|
||||||
|
SHRQ $20, SI
|
||||||
|
SHRQ $34, R8
|
||||||
|
ANDL $-16, SI
|
||||||
|
ANDL $15, R8
|
||||||
|
ORL R8, SI
|
||||||
|
MOVB SI, 3(R9)(CX*1)
|
||||||
|
CMPL BX, $4
|
||||||
|
JE decend
|
||||||
|
|
||||||
|
MOVQ DX, SI
|
||||||
|
SHRQ $42, DX
|
||||||
|
SHRQ $26, SI
|
||||||
|
ANDL $63, DX
|
||||||
|
ANDL $-64, SI
|
||||||
|
ORL SI, DX
|
||||||
|
MOVB DX, 4(R9)(CX*1)
|
||||||
|
CMPL BX, $5
|
||||||
|
JE decend
|
||||||
|
|
||||||
|
MOVQ $-21955383195992142, DX
|
||||||
|
ADDQ DX, DI
|
||||||
|
MOVQ DI, DX
|
||||||
|
SHRQ $48, DI
|
||||||
|
SHRQ $34, DX
|
||||||
|
ANDL $63, DI
|
||||||
|
ANDL $-64, DX
|
||||||
|
ORL DI, DX
|
||||||
|
MOVB DX, 5(R9)(CX*1)
|
||||||
|
|
||||||
|
decend:
|
||||||
|
RET
|
||||||
10
base14_asm.go
Normal file
10
base14_asm.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
//go:build amd64
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package base14
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func encode(offset, outlen int, b, encd []byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func decode(offset, outlen int, b, decd []byte)
|
||||||
105
base14_generic.go
Normal file
105
base14_generic.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
//go:build !amd64
|
||||||
|
// +build !amd64
|
||||||
|
|
||||||
|
package base14
|
||||||
|
|
||||||
|
import "encoding/binary"
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func encode(offset, outlen int, b, encd []byte) {
|
||||||
|
var n int
|
||||||
|
i := 0
|
||||||
|
for ; i <= len(b)-7; i += 7 {
|
||||||
|
shift := binary.BigEndian.Uint64(b[i:]) >> 2
|
||||||
|
sum := shift
|
||||||
|
sum &= 0x3fff000000000000
|
||||||
|
shift >>= 2
|
||||||
|
sum |= shift & 0x00003fff00000000
|
||||||
|
shift >>= 2
|
||||||
|
sum |= shift & 0x000000003fff0000
|
||||||
|
shift >>= 2
|
||||||
|
sum |= shift & 0x0000000000003fff
|
||||||
|
sum += 0x4e004e004e004e00
|
||||||
|
binary.BigEndian.PutUint64(encd[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
|
||||||
|
var tmp [8]byte
|
||||||
|
binary.LittleEndian.PutUint64(tmp[:], sum)
|
||||||
|
copy(encd[n:], tmp[:])
|
||||||
|
encd[outlen-2] = '='
|
||||||
|
encd[outlen-1] = byte(offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func decode(offset, outlen int, b, decd []byte) {
|
||||||
|
var n uintptr
|
||||||
|
i := 0
|
||||||
|
for ; i <= outlen-7; n += 8 {
|
||||||
|
shift := binary.BigEndian.Uint64(b[n:]) - 0x4e004e004e004e00
|
||||||
|
shift <<= 2
|
||||||
|
sum := shift & 0xfffc000000000000
|
||||||
|
shift <<= 2
|
||||||
|
sum |= shift & 0x0003fff000000000
|
||||||
|
shift <<= 2
|
||||||
|
sum |= shift & 0x0000000fffc00000
|
||||||
|
shift <<= 2
|
||||||
|
sum |= shift & 0x00000000003fff00
|
||||||
|
binary.BigEndian.PutUint64(decd[i:], sum)
|
||||||
|
i += 7
|
||||||
|
}
|
||||||
|
if offset > 0 {
|
||||||
|
var tmp [8]byte
|
||||||
|
copy(tmp[:], b[n:])
|
||||||
|
sum := binary.LittleEndian.Uint64(tmp[:]) - 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++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package base14
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -10,10 +11,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBase14(t *testing.T) {
|
func TestBase14(t *testing.T) {
|
||||||
teststr := "一个测试293大大的啊定位为恶的我284的我……#@%@%@"
|
assert.Equal(t, "蜮嘎惢磦筢貊豔耹嫹桊涖犧蟦癎摖壥禦籋萷犸粹瘛榞梄螢圓因苧璡屨灇炀瞸瘊暍严帉戀㴃", EncodeString("一个测试293大大的啊定位为恶的我284的我……#@%@%@"))
|
||||||
es := EncodeString(teststr)
|
assert.Equal(t, "婀㴁", EncodeString("1"))
|
||||||
assert.Equal(t, "蜮嘎惢磦筢貊豔耹嫹桊涖犧蟦癎摖壥禦籋萷犸粹瘛榞梄螢圓因苧璡屨灇炀瞸瘊暍严帉戀㴃", es)
|
assert.Equal(t, "婌渀㴂", EncodeString("12"))
|
||||||
assert.Equal(t, teststr, DecodeString(es))
|
assert.Equal(t, "婌焰㴃", EncodeString("123"))
|
||||||
|
assert.Equal(t, "婌焳帀㴄", EncodeString("1234"))
|
||||||
|
assert.Equal(t, "婌焳廔㴅", EncodeString("12345"))
|
||||||
|
assert.Equal(t, "婌焳廔萀㴆", EncodeString("123456"))
|
||||||
|
assert.Equal(t, "婌焳廔萷", EncodeString("1234567"))
|
||||||
|
assert.Equal(t, "婌焳廔萷尀㴁", EncodeString("12345678"))
|
||||||
|
buf := make([]byte, 4096)
|
||||||
|
for i := 1; i < 4096; i++ {
|
||||||
|
rand.Read(buf[:i])
|
||||||
|
out := Decode(Encode(buf[:i]))
|
||||||
|
assert.Equal(t, hex.EncodeToString(buf[:i]), hex.EncodeToString(out))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncoder(t *testing.T) {
|
func TestEncoder(t *testing.T) {
|
||||||
|
|||||||
8
go.mod
8
go.mod
@@ -1,8 +1,14 @@
|
|||||||
module github.com/fumiama/go-base16384
|
module github.com/fumiama/go-base16384
|
||||||
|
|
||||||
go 1.16
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.7.1
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
|
)
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -7,7 +7,6 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT
|
|||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
|||||||
Reference in New Issue
Block a user