package utils import ( "crypto/rand" "crypto/sha256" "encoding/base64" "fmt" "log" randa "math/rand" "time" "golang.org/x/crypto/bcrypt" ) type Crypto struct{} func (*Crypto) PasswordEncryption(password string) (string, error) { cost := 10 hashedBytes, err := bcrypt.GenerateFromPassword([]byte(password), cost) if err != nil { log.Fatal("加密失败:", err) return "", err } hashedPassword := string(hashedBytes) fmt.Println("加密后的哈希值:", hashedPassword) return hashedPassword, nil } func (*Crypto) PasswordVerify(hash, password string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } func (*Crypto) GenerateStateToken(tokenLength int) (string, error) { // 1. 生成密码学安全的随机字节 randomBytes := make([]byte, tokenLength) _, err := rand.Read(randomBytes) if err != nil { return "", fmt.Errorf("生成随机数失败: %w", err) } // 2. (可选) 加入时间戳作为额外熵源,进一步降低碰撞和重放风险 // 注意:如果你需要验证 token 的新鲜度(如设置有效期),时间戳信息需要单独存储,因为哈希本身不可逆。 currentTime := time.Now().UnixNano() timeBytes := make([]byte, 8) // 简单地将时间戳转为字节序列,这里使用大端序 for i := 0; i < 8; i++ { timeBytes[i] = byte(currentTime >> (56 - i*8)) } // 将随机字节和时间戳字节组合 dataToHash := append(randomBytes, timeBytes...) // 3. 对组合后的数据进行 SHA-256 哈希 hash := sha256.Sum256(dataToHash) // 4. 将哈希结果转换为字符串(这里使用 Base64 编码) token := base64.URLEncoding.EncodeToString(hash[:]) return token, nil } func (*Crypto) GetRandString(length int) string { // 初始化随机数种子 randa.Seed(time.Now().UnixNano()) const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // 方法1: 使用字节切片 b := make([]byte, length) for i := range b { b[i] = letters[randa.Intn(len(letters))] // 随机选取一个字符 } randomString := string(b) return randomString }