Speedup encode base58 lookup, slice data

This commit is contained in:
DataHoarder 2023-05-27 13:48:44 +02:00
parent 113843a69c
commit 7d37dcb5ae
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk

View file

@ -6,15 +6,39 @@ import (
const BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
var base58Lookup = map[string]int{
"1": 0, "2": 1, "3": 2, "4": 3, "5": 4, "6": 5, "7": 6, "8": 7,
"9": 8, "A": 9, "B": 10, "C": 11, "D": 12, "E": 13, "F": 14, "G": 15,
"H": 16, "J": 17, "K": 18, "L": 19, "M": 20, "N": 21, "P": 22, "Q": 23,
"R": 24, "S": 25, "T": 26, "U": 27, "V": 28, "W": 29, "X": 30, "Y": 31,
"Z": 32, "a": 33, "b": 34, "c": 35, "d": 36, "e": 37, "f": 38, "g": 39,
"h": 40, "i": 41, "j": 42, "k": 43, "m": 44, "n": 45, "o": 46, "p": 47,
"q": 48, "r": 49, "s": 50, "t": 51, "u": 52, "v": 53, "w": 54, "x": 55,
"y": 56, "z": 57,
var base58Lookup = map[uint8]uint8{
'1': 0, '2': 1, '3': 2, '4': 3, '5': 4, '6': 5, '7': 6, '8': 7, '9': 8,
'A': 9, 'B': 10, 'C': 11, 'D': 12, 'E': 13, 'F': 14, 'G': 15, 'H': 16,
'J': 17, 'K': 18, 'L': 19, 'M': 20, 'N': 21,
'P': 22, 'Q': 23, 'R': 24, 'S': 25, 'T': 26, 'U': 27, 'V': 28, 'W': 29, 'X': 30, 'Y': 31, 'Z': 32,
'a': 33, 'b': 34, 'c': 35, 'd': 36, 'e': 37, 'f': 38, 'g': 39, 'h': 40, 'i': 41, 'j': 42, 'k': 43,
'm': 44, 'n': 45, 'o': 46, 'p': 47, 'q': 48, 'r': 49, 's': 50, 't': 51, 'u': 52, 'v': 53, 'w': 54, 'x': 55, 'y': 56, 'z': 57,
}
func slowBase58Lookup(c uint8) uint8 {
return base58Lookup[c]
}
func fastBase58Lookup(c uint8) uint8 {
if c >= '1' && c <= '9' {
return c - '1'
} else if c >= 'A' && c <= 'H' {
return c - 'A' + 9
} else if c >= 'J' && c <= 'N' {
return c - 'J' + 17
} else if c >= 'P' && c <= 'Z' {
return c - 'P' + 22
} else if c >= 'a' && c <= 'k' {
return c - 'a' + 33
} else if c >= 'm' && c <= 'z' {
return c - 'm' + 44
}
return 0
}
var base128 = uint128.From64(58)
@ -37,37 +61,37 @@ func encodeChunk(raw []byte, padding int, buf []byte) []byte {
return buf
}
func decodeChunk(encoded string) (result []byte) {
func decodeChunk(buf []byte, encoded string) (result []byte) {
var bigResult uint128.Uint128
currentMultiplier := uint128.From64(1)
for i := len(encoded) - 1; i >= 0; i-- {
bigResult = bigResult.Add(currentMultiplier.Mul64(uint64(base58Lookup[string(encoded[i])])))
bigResult = bigResult.Add(currentMultiplier.Mul64(uint64(fastBase58Lookup(encoded[i]))))
currentMultiplier = currentMultiplier.Mul(base128)
}
result = make([]byte, 16)
bigResult.ReverseBytes().PutBytes(result)
switch len(encoded) {
case 0:
return result[8+8:]
return append(buf, result[8+8:]...)
case 2:
return result[8+7:]
return append(buf, result[8+7:]...)
case 3:
return result[8+6:]
return append(buf, result[8+6:]...)
case 5:
return result[8+5:]
return append(buf, result[8+5:]...)
case 6:
return result[8+4:]
return append(buf, result[8+4:]...)
case 7:
return result[8+3:]
return append(buf, result[8+3:]...)
case 9:
return result[8+2:]
return append(buf, result[8+2:]...)
case 10:
return result[8+1:]
return append(buf, result[8+1:]...)
case 11:
return result[8:]
return append(buf, result[8:]...)
default:
}
return nil
return buf
}
func EncodeMoneroBase58(data ...[]byte) string {
@ -100,10 +124,10 @@ func DecodeMoneroBase58PreAllocated(buf []byte, data string) (result []byte) {
length := len(data)
rounds := length / 11
for i := 0; i < rounds; i++ {
result = append(result, decodeChunk(data[i*11:i*11+11])...)
result = decodeChunk(result, data[i*11:i*11+11])
}
if length%11 > 0 {
result = append(result, decodeChunk(data[rounds*11:])...)
result = decodeChunk(result, data[rounds*11:])
}
return
}