您的位置 首页 golang

GO 里面的比较好用的一些工具方法【值得收藏】

今天在一个源码里面看到里面的 util 包,里面的好多的工具都是我们可以直接拿来使用的,之前没有这个习惯,所以每次就喜欢到处找。现在开始在这些源码里面去记录一下。方便日后的使用。

// 这里是引入的包import (    "crypto/rand"    "crypto/sha256"    "crypto/md5"    "encoding/base64"    "encoding/hex"    "errors"    "golang.org/x/crypto/pbkdf2"    "strings"    "github.com/grafana/grafana/pkg/util/errutil")

Encode 操作

// GetRandomString generate random string by specify chars.// 通过指定字符生成随机字符串func GetRandomString(n int, alphabets ...byte) (string, error) {    const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"    var bytes = make([]byte, n)    if _, err := rand.Read(bytes); err != nil {        return "", err    }    for i, b := range bytes {        if len(alphabets) == 0 {            bytes[i] = alphanum[b%byte(len(alphanum))]        } else {            bytes[i] = alphabets[b%byte(len(alphabets))]        }    }    return string(bytes), nil}// EncodePassword encodes a password using PBKDF2.// 使用PBKDF2对密码进行编码func EncodePassword(password string, salt string) (string, error) {    newPasswd := pbkdf2.Key([]byte(password), []byte(salt), 10000, 50, sha256.New)    return hex.EncodeToString(newPasswd), nil}// GetBasicAuthHeader returns a base64 encoded string from user and password.// 从用户和密码返回base64编码的字符串。func GetBasicAuthHeader(user string, password string) string {    var userAndPass = user + ":" + password    return "Basic " + base64.StdEncoding.EncodeToString([]byte(userAndPass))}// DecodeBasicAuthHeader decodes user and password from a basic auth header.// 从基本的auth标头解码用户和密码。func DecodeBasicAuthHeader(header string) (string, string, error) {    var code string    parts := strings.SplitN(header, " ", 2)    if len(parts) == 2 && parts[0] == "Basic" {        code = parts[1]    }    decoded, err := base64.StdEncoding.DecodeString(code)    if err != nil {        return "", "", err    }    userAndPass := strings.SplitN(string(decoded), ":", 2)    if len(userAndPass) != 2 {        return "", "", errors.New("Invalid basic auth header")    }    return userAndPass[0], userAndPass[1], nil}// RandomHex returns a random string from a n seed.// 从n个种子返回一个随机字符串。func RandomHex(n int) (string, error) {    bytes := make([]byte, n)    if _, err := rand.Read(bytes); err != nil {        return "", err    }    return hex.EncodeToString(bytes), nil}

Decrypt / Encrypt

// Decrypt decrypts a payload with a given secret.func Decrypt(payload []byte, secret string) ([]byte, error) {    salt := payload[:saltLength]    key, err := encryptionKeyToBytes(secret, string(salt))    if err != nil {        return nil, err    }    block, err := aes.NewCipher(key)    if err != nil {        return nil, err    }    // The IV needs to be unique, but not secure. Therefore it's common to    // include it at the beginning of the ciphertext.    if len(payload) < aes.BlockSize {        return nil, errors.New("payload too short")    }    iv := payload[saltLength : saltLength+aes.BlockSize]    payload = payload[saltLength+aes.BlockSize:]    payloadDst := make([]byte, len(payload))    stream := cipher.NewCFBDecrypter(block, iv)    // XORKeyStream can work in-place if the two arguments are the same.    stream.XORKeyStream(payloadDst, payload)    return payloadDst, nil}// Encrypt encrypts a payload with a given secret.func Encrypt(payload []byte, secret string) ([]byte, error) {    salt, err := GetRandomString(saltLength)    if err != nil {        return nil, err    }    key, err := encryptionKeyToBytes(secret, salt)    if err != nil {        return nil, err    }    block, err := aes.NewCipher(key)    if err != nil {        return nil, err    }    // The IV needs to be unique, but not secure. Therefore it's common to    // include it at the beginning of the ciphertext.    ciphertext := make([]byte, saltLength+aes.BlockSize+len(payload))    copy(ciphertext[:saltLength], []byte(salt))    iv := ciphertext[saltLength : saltLength+aes.BlockSize]    if _, err := io.ReadFull(rand.Reader, iv); err != nil {        return nil, err    }    stream := cipher.NewCFBEncrypter(block, iv)    stream.XORKeyStream(ciphertext[saltLength+aes.BlockSize:], payload)    return ciphertext, nil}// Key needs to be 32bytesfunc encryptionKeyToBytes(secret, salt string) ([]byte, error) {    return pbkdf2.Key([]byte(secret), []byte(salt), 10000, 32, sha256.New), nil}

MD5 操作

// Md5Sum calculates the md5sum of a stream// 计算流的md5sumfunc Md5Sum(reader io.Reader) (string, error) {    var returnMD5String string    hash := md5.New()    if _, err := io.Copy(hash, reader); err != nil {        return returnMD5String, err    }    hashInBytes := hash.Sum(nil)[:16]    returnMD5String = hex.EncodeToString(hashInBytes)    return returnMD5String, nil}// Md5SumString calculates the md5sum of a string// 计算字符串的md5sumfunc Md5SumString(input string) (string, error) {    buffer := strings.NewReader(input)    return Md5Sum(buffer)}

IP 操作

// ParseIPAddress parses an IP address and removes port and/or IPV6 formatfunc ParseIPAddress(input string) (string, error) {    addr, err := SplitHostPort(input)    if err != nil {        return "", errutil.Wrapf(err, "Failed to split network address '%s' by host and port",            input)    }    ip := net.ParseIP(addr.Host)    if ip == nil {        return addr.Host, nil    }    if ip.IsLoopback() {        if strings.Contains(addr.Host, ":") {            // IPv6            return "::1", nil        }        return "127.0.0.1", nil    }    return ip.String(), nil}type NetworkAddress struct {    Host string    Port string}// SplitHostPortDefault splits ip address/hostname string by host and port. Defaults used if no match foundfunc SplitHostPortDefault(input, defaultHost, defaultPort string) (NetworkAddress, error) {    addr := NetworkAddress{        Host: defaultHost,        Port: defaultPort,    }    if len(input) == 0 {        return addr, nil    }    start := 0    // Determine if IPv6 address, in which case IP address will be enclosed in square brackets    if strings.Index(input, "[") == 0 {        addrEnd := strings.LastIndex(input, "]")        if addrEnd < 0 {            // Malformed address            return addr, fmt.Errorf("Malformed IPv6 address: '%s'", input)        }        start = addrEnd    }    if strings.LastIndex(input[start:], ":") < 0 {        // There's no port section of the input        // It's still useful to call net.SplitHostPort though, since it removes IPv6        // square brackets from the address        input = fmt.Sprintf("%s:%s", input, defaultPort)    }    host, port, err := net.SplitHostPort(input)    if err != nil {        return addr, errutil.Wrapf(err, "net.SplitHostPort failed for '%s'", input)    }    if len(host) > 0 {        addr.Host = host    }    if len(port) > 0 {        addr.Port = port    }    return addr, nil}// SplitHostPort splits ip address/hostname string by host and portfunc SplitHostPort(input string) (NetworkAddress, error) {    if len(input) == 0 {        return NetworkAddress{}, fmt.Errorf("Input is empty")    }    return SplitHostPortDefault(input, "", "")}

文章来源:智云一二三科技

文章标题:GO 里面的比较好用的一些工具方法【值得收藏】

文章地址:https://www.zhihuclub.com/6525.shtml

关于作者: 智云科技

热门文章

网站地图