slice填充

区块链底层使用merkle tree,需要对数据([]byte)进行填充等操作。 本文封装了这些操作。

源码结构:

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

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

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
}

执行结果:

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#

猜你喜欢

转载自blog.csdn.net/jacky128256/article/details/119029219