diff --git a/base14.go b/base14.go index 8f58382..6c1ab0c 100644 --- a/base14.go +++ b/base14.go @@ -40,7 +40,7 @@ func Encode(b []byte) (encd []byte) { outlen += 10 } encd = make([]byte, outlen) - encode(offset, outlen, append(b, 0), encd) + encode(offset, outlen, b, encd) return } @@ -62,7 +62,7 @@ func EncodeTo(b, encd []byte) error { if len(encd) < outlen { return errors.New("encd too small") } - encode(offset, outlen, append(b, 0), encd) + encode(offset, outlen, b, encd) return nil } @@ -105,7 +105,7 @@ func Decode(b []byte) (decd []byte) { } } outlen = outlen/8*7 + offset - decd = make([]byte, outlen+1) + decd = make([]byte, outlen+8) decode(offset, outlen, b, decd) return decd[:outlen] } diff --git a/base14_amd64.s b/base14_amd64.s index fb2beb0..685b3c6 100644 --- a/base14_amd64.s +++ b/base14_amd64.s @@ -3,8 +3,8 @@ #include "textflag.h" -// func encode(offset, outlen int, b, encd []byte) -TEXT ·encode(SB), NOSPLIT, $0-64 +// func _encode(offset, outlen int, b, encd []byte) (sum uint64, n uint64) +TEXT ·_encode(SB), NOSPLIT, $0-81 MOVQ ·offset+0(FP), R10 MOVQ ·outlen+8(FP), AX MOVQ ·data+16(FP), DI @@ -116,16 +116,16 @@ encrem: 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) + SHLQ $3, SI + MOVQ DX, ·sum+64(FP) + MOVQ SI, ·sum+72(FP) encend: RET -// func decode(offset, outlen int, b, decd []byte) -TEXT ·decode(SB), NOSPLIT, $0-64 +// func _decode(offset, outlen int, b, decd []byte) +TEXT ·_decode(SB), NOSPLIT, $0-64 MOVQ ·offset+0(FP), BX MOVQ ·outlen+8(FP), R8 MOVQ ·data+16(FP), DI diff --git a/base14_asm.go b/base14_asm.go index 4ba6ec1..ae64d06 100644 --- a/base14_asm.go +++ b/base14_asm.go @@ -3,10 +3,36 @@ package base14 -//go:noescape -//go:nosplit -func encode(offset, outlen int, b, encd []byte) +import ( + "encoding/binary" +) //go:noescape //go:nosplit -func decode(offset, outlen int, b, decd []byte) +func _encode(offset, outlen int, b, encd []byte) (sum uint64, n uint64) + +//go:noescape +//go:nosplit +func _decode(offset, outlen int, b, decd []byte) + +func encode(offset, outlen int, b, encd []byte) { + if len(b) == 7 { + b = append(b, 0) + } + sum, n := _encode(offset, outlen, b, encd) + if offset == 0 { + return + } + var tmp [8]byte + binary.LittleEndian.PutUint64(tmp[:], sum) + copy(encd[n:], tmp[:]) + encd[outlen-2] = '=' + encd[outlen-1] = byte(offset) +} + +func decode(offset, outlen int, b, decd []byte) { + if offset != 0 && cap(b) == len(b) { + b = append(b, make([]byte, 8)...) + } + _decode(offset, outlen, b, decd) +}