新增部分模块
This commit is contained in:
56
utils/crypto.go
Normal file
56
utils/crypto.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"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) 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
|
||||
}
|
||||
86
utils/generate_id.go
Normal file
86
utils/generate_id.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 定义常量
|
||||
const (
|
||||
twepoch = int64(1577836800000) // 起始时间戳 (2020-01-01 00:00:00 UTC 的毫秒数)
|
||||
workerIDBits = 5 // 工作节点 ID 的位数
|
||||
datacenterIDBits = 5 // 数据中心 ID 的位数
|
||||
sequenceBits = 12 // 序列号的位数
|
||||
|
||||
// 计算最大值
|
||||
maxWorkerID = -1 ^ (-1 << workerIDBits) // 最大工作节点 ID
|
||||
maxDatacenterID = -1 ^ (-1 << datacenterIDBits) // 最大数据中心 ID
|
||||
maxSequence = -1 ^ (-1 << sequenceBits) // 最大序列号
|
||||
|
||||
// 定义移位偏移量
|
||||
workerIDShift = sequenceBits
|
||||
datacenterIDShift = sequenceBits + workerIDBits
|
||||
timestampShift = sequenceBits + workerIDBits + datacenterIDBits
|
||||
)
|
||||
|
||||
// Snowflake 结构体
|
||||
type Snowflake struct {
|
||||
mu sync.Mutex
|
||||
lastTimestamp int64
|
||||
workerID int64
|
||||
datacenterID int64
|
||||
sequence int64
|
||||
}
|
||||
|
||||
// NewSnowflake 初始化 Snowflake 实例
|
||||
func NewSnowflake(workerID, datacenterID int64) (*Snowflake, error) {
|
||||
if workerID < 0 || workerID > maxWorkerID {
|
||||
return nil, fmt.Errorf("worker ID must be between 0 and %d", maxWorkerID)
|
||||
}
|
||||
if datacenterID < 0 || datacenterID > maxDatacenterID {
|
||||
return nil, fmt.Errorf("datacenter ID must be between 0 and %d", maxDatacenterID)
|
||||
}
|
||||
return &Snowflake{
|
||||
lastTimestamp: -1,
|
||||
workerID: workerID,
|
||||
datacenterID: datacenterID,
|
||||
sequence: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NextID 生成唯一 ID
|
||||
func (s *Snowflake) NextID() int64 {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
timestamp := time.Now().UnixNano() / 1e6 // 当前毫秒时间戳
|
||||
|
||||
// 如果当前时间小于上次生成 ID 的时间,说明系统时钟可能回退,返回错误或等待
|
||||
if timestamp < s.lastTimestamp {
|
||||
panic(fmt.Sprintf("clock moved backwards. refusing to generate id for %d milliseconds", s.lastTimestamp-timestamp))
|
||||
}
|
||||
|
||||
// 如果是同一毫秒内生成的,则递增序列号
|
||||
if timestamp == s.lastTimestamp {
|
||||
s.sequence = (s.sequence + 1) & maxSequence
|
||||
// 如果序列号超过最大值,则等待下一毫秒
|
||||
if s.sequence == 0 {
|
||||
for timestamp <= s.lastTimestamp {
|
||||
timestamp = time.Now().UnixNano() / 1e6
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.sequence = 0
|
||||
}
|
||||
|
||||
s.lastTimestamp = timestamp
|
||||
|
||||
// 组合各部分生成最终 ID
|
||||
id := ((timestamp - twepoch) << timestampShift) |
|
||||
(s.datacenterID << datacenterIDShift) |
|
||||
(s.workerID << workerIDShift) |
|
||||
s.sequence
|
||||
|
||||
return id
|
||||
}
|
||||
Reference in New Issue
Block a user