185 lines
4.6 KiB
Go
185 lines
4.6 KiB
Go
package utilsx
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha1"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
"math/big"
|
|
"strings"
|
|
)
|
|
|
|
// GenerateRandomString 生成指定长度的随机字符串
|
|
func GenerateRandomString(length int) (string, error) {
|
|
if length <= 0 {
|
|
return "", fmt.Errorf("长度必须大于0")
|
|
}
|
|
|
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
result := make([]byte, length)
|
|
|
|
for i := range result {
|
|
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
|
|
if err != nil {
|
|
return "", fmt.Errorf("生成随机数失败: %v", err)
|
|
}
|
|
result[i] = charset[num.Int64()]
|
|
}
|
|
|
|
return string(result), nil
|
|
}
|
|
|
|
// GenerateRandomBytes 生成指定长度的随机字节
|
|
func GenerateRandomBytes(length int) ([]byte, error) {
|
|
if length <= 0 {
|
|
return nil, fmt.Errorf("长度必须大于0")
|
|
}
|
|
|
|
bytes := make([]byte, length)
|
|
_, err := rand.Read(bytes)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("生成随机字节失败: %v", err)
|
|
}
|
|
|
|
return bytes, nil
|
|
}
|
|
|
|
// GenerateRandomHexString 生成指定长度的随机十六进制字符串
|
|
func GenerateRandomHexString(length int) (string, error) {
|
|
bytes, err := GenerateRandomBytes(length)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(bytes), nil
|
|
}
|
|
|
|
// GenerateRandomBase64String 生成指定长度的随机Base64字符串
|
|
func GenerateRandomBase64String(length int) (string, error) {
|
|
bytes, err := GenerateRandomBytes(length)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return base64.StdEncoding.EncodeToString(bytes), nil
|
|
}
|
|
|
|
// CalculateHash 计算字符串的哈希值
|
|
func CalculateHash(input string) string {
|
|
h := sha1.New()
|
|
h.Write([]byte(input))
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
// GenerateUUID 生成UUID v4
|
|
func GenerateUUID() (string, error) {
|
|
bytes := make([]byte, 16)
|
|
_, err := rand.Read(bytes)
|
|
if err != nil {
|
|
return "", fmt.Errorf("生成UUID失败: %v", err)
|
|
}
|
|
|
|
// 设置版本号和变体
|
|
bytes[6] = (bytes[6] & 0x0f) | 0x40 // Version 4
|
|
bytes[8] = (bytes[8] & 0x3f) | 0x80 // Variant 10
|
|
|
|
return fmt.Sprintf("%x-%x-%x-%x-%x", bytes[0:4], bytes[4:6], bytes[6:8], bytes[8:10], bytes[10:16]), nil
|
|
}
|
|
|
|
// GenerateAPIKey 生成API密钥
|
|
func GenerateAPIKey(prefix string) (string, error) {
|
|
// 生成24字节的随机数据
|
|
randomBytes, err := GenerateRandomBytes(24)
|
|
if err != nil {
|
|
return "", fmt.Errorf("生成API密钥失败: %v", err)
|
|
}
|
|
|
|
// 转换为Base64
|
|
apiKey := base64.StdEncoding.EncodeToString(randomBytes)
|
|
|
|
// 添加前缀(如果有)
|
|
if prefix != "" {
|
|
apiKey = prefix + "." + apiKey
|
|
}
|
|
|
|
return apiKey, nil
|
|
}
|
|
|
|
// GenerateToken 生成安全令牌
|
|
func GenerateToken(length int) (string, error) {
|
|
if length <= 0 {
|
|
return "", fmt.Errorf("长度必须大于0")
|
|
}
|
|
|
|
// 生成足够的随机字节,确保Base64编码后至少有指定长度
|
|
bytesNeeded := (length*3 + 3) / 4 // Base64编码会使长度增加约33%
|
|
bytes, err := GenerateRandomBytes(bytesNeeded)
|
|
if err != nil {
|
|
return "", fmt.Errorf("生成令牌失败: %v", err)
|
|
}
|
|
|
|
// 转换为Base64 URL安全编码(无填充,URL和文件名安全)
|
|
token := base64.URLEncoding.EncodeToString(bytes)
|
|
|
|
// 移除填充字符
|
|
token = strings.TrimRight(token, "=")
|
|
|
|
// 确保令牌长度符合要求
|
|
if len(token) > length {
|
|
token = token[:length]
|
|
}
|
|
|
|
return token, nil
|
|
}
|
|
|
|
// GeneratePassword 生成密码
|
|
func GeneratePassword(length int, useUppercase, useLowercase, useDigits, useSymbols bool) (string, error) {
|
|
if length <= 0 {
|
|
return "", fmt.Errorf("密码长度必须大于0")
|
|
}
|
|
|
|
var charset string
|
|
if useUppercase {
|
|
charset += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
}
|
|
if useLowercase {
|
|
charset += "abcdefghijklmnopqrstuvwxyz"
|
|
}
|
|
if useDigits {
|
|
charset += "0123456789"
|
|
}
|
|
if useSymbols {
|
|
charset += "!@#$%^&*()-_=+[]{}|;:,.<>?"
|
|
}
|
|
|
|
if charset == "" {
|
|
return "", fmt.Errorf("至少选择一种字符类型")
|
|
}
|
|
|
|
// 确保密码包含所有选择的字符类型
|
|
password := make([]byte, length)
|
|
charsetLength := big.NewInt(int64(len(charset)))
|
|
|
|
for i := 0; i < length; i++ {
|
|
num, err := rand.Int(rand.Reader, charsetLength)
|
|
if err != nil {
|
|
return "", fmt.Errorf("生成密码失败: %v", err)
|
|
}
|
|
password[i] = charset[num.Int64()]
|
|
}
|
|
|
|
return string(password), nil
|
|
}
|
|
|
|
// HashPassword 哈希密码(简单示例,实际应用中应使用更安全的算法如bcrypt)
|
|
func HashPassword(password, salt string) string {
|
|
h := sha1.New()
|
|
io.WriteString(h, password+salt)
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
// VerifyPassword 验证密码(简单示例,实际应用中应使用更安全的算法如bcrypt)
|
|
func VerifyPassword(password, salt, hash string) bool {
|
|
return HashPassword(password, salt) == hash
|
|
}
|