> 区块链底层使用merkle tree,需要对数据([]byte)进行填充等操作。 本文封装了这些操作。
源码结构:
```shell
root@jack-VirtualBox:~/test/slice# tree
.
├── go.mod
├── go.sum
├── main.go
├── misc
│ └── util.go
└── tt
1 directory, 5 files
root@jack-VirtualBox:~/test/slice#
```
**main.go**
```go
package main
import (
"fmt"
"tt/misc"
)
func main() {
fmt.Println("vim-go")
by := misc.Bytes{'h', 'e', 'l', 'l', 'o'}
fmt.Println(string(by))
// 字节 -> 0xddddddd十六进制字符串
hby, err := by.MarshalText()
if err == nil {
fmt.Println(string(hby))
}
newby := &misc.Bytes{}
err = newby.UnmarshalText(hby)
if err == nil {
fmt.Println(string(*newby))
}
// 深拷贝字节切片
dd := []byte("hello jack")
ds := misc.CopyBytes(dd)
fmt.Printf("%s, %s, %p, %p\r\n", string(ds), string(dd), ds, dd)
// 随机打乱字节切片的数据
misc.Shuffle(dd)
fmt.Println(string(dd))
misc.Shuffle(ds)
fmt.Println(string(ds))
// 左对齐填充容器
as := []byte("hello jack")
aa := misc.RightPadBytes(as, 100)
fmt.Println("-------测试右填充")
fmt.Println(as, "\r\n", aa)
// 右对齐填充容器
kk := misc.LeftPadBytes(as, 300)
fmt.Println("-------测试左填充")
fmt.Println(as, "\r\n", kk)
}
```
**misc/util.go**
```go
package misc
import (
"encoding/hex"
"errors"
"math/rand"
"reflect"
"time"
lru "github.com/hashicorp/golang-lru"
)
// Bytes is a array byte that is converted to hex string display format when marshal
type Bytes []byte
// Has0xPrefix returns true if input start with 0x, otherwise false
func Has0xPrefix(input string) bool {
return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
}
// BytesToHex encodes b as a hex string with 0x prefix.
func BytesToHex(b []byte) string {
enc := make([]byte, len(b)*2+2)
copy(enc, "0x")
hex.Encode(enc[2:], b)
return string(enc)
}
// HexToBytes decodes a hex string with 0x prefix.
func HexToBytes(input string) ([]byte, error) {
if len(input) == 0 {
return nil, errors.New("empty hex string")
}
// MissingPrefix
if !Has0xPrefix(input) {
return nil, errors.New("empty hex string")
}
b, err := hex.DecodeString(input[2:])
if err != nil {
return nil, err
}
return b, nil
}
// MarshalText implement the TextMarshaler interface
func (b Bytes) MarshalText() ([]byte, error) {
if len(b) == 0 {
return nil, nil
}
hex := BytesToHex(b)
return []byte(hex), nil
}
// UnmarshalText implement the TextUnmarshaler interface
func (b *Bytes) UnmarshalText(hex []byte) error {
if len(hex) == 0 {
return nil
}
arrayByte, err := HexToBytes(string(hex))
if err != nil {
return err
}
*b = arrayByte
return nil
}
// CopyBytes copies and returns a new bytes from the specified source bytes.
func CopyBytes(src []byte) []byte {
if src == nil {
return nil
}
dest := make([]byte, len(src))
copy(dest, src)
return dest
}
// MustNewCache creates a LRU cache with specified size. Panics on any error.
func MustNewCache(size int) *lru.Cache {
cache, err := lru.New(size)
if err != nil {
panic(err) // error occurs only when size <= 0.
}
return cache
}
// Shuffle shuffles items in slice
func Shuffle(slice interface{}) {
rv := reflect.ValueOf(slice)
swap := reflect.Swapper(slice)
length := rv.Len()
for i := length - 1; i > 0; i-- {
rand.Seed(time.Now().UnixNano())
j := rand.Intn(i + 1)
swap(i, j)
}
}
// RightPadBytes zero-pads slice to the right up to length l.
func RightPadBytes(slice []byte, l int) []byte {
if l <= len(slice) {
return slice
}
padded := make([]byte, l)
copy(padded, slice)
return padded
}
// LeftPadBytes zero-pads slice to the left up to length l.
func LeftPadBytes(slice []byte, l int) []byte {
if l <= len(slice) {
return slice
}
padded := make([]byte, l)
copy(padded[l-len(slice):], slice)
return padded
}
```
执行结果:
```shell
root@jack-VirtualBox:~/test/slice# ./tt
vim-go
hello
0x68656c6c6f
hello
hello jack, hello jack, 0xc000014130, 0xc000014120
jc hkealol
halclekjo
-------测试右填充
[104 101 108 108 111 32 106 97 99 107]
[104 101 108 108 111 32 106 97 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
-------测试左填充
[104 101 108 108 111 32 106 97 99 107]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 104 101 108 108 111 32 106 97 99 107]
root@jack-VirtualBox:~/test/slice#
```
有疑问加站长微信联系(非本文作者))