今天在一个源码里面看到里面的 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