随机值

math/rand

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	s := rand.NewSource(time.Now().Unix())
	rd := rand.New(s)
	fmt.Println(rd.Intn(100))
}
package main

import (
	"crypto/rand"
	"fmt"
	"math/big"
)

func main() {
	// 生成 0 到 10 的随机整数
	randInt, _ := rand.Int(rand.Reader, big.NewInt(11)) // 生成 0 到 10 的随机整数
	randomNum := randInt.Int64()

	fmt.Println(randomNum)
	//生成数组
	td, _ := GenerateRandomBytes(5)
	var ints = make([]int, len(td))
	for i, b := range td {
		ints[i] = int(b)
	}
	fmt.Println(ints)
}

func GenerateRandomBytes(n int) ([]byte, error) {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		return nil, err
	}
	return b, nil
}

生成随机 Token

在实际业务中经常需要生成随机 Token(如 API Key、会话令牌等),思路是先用 crypto/rand 读取指定字节数的密码学安全随机值,再用 hex.EncodeToString 编码为十六进制字符串。最终字符串长度是字节数的 2 倍,例如传入 32 得到 64 位字符的 Token:

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
)

func onboardGenerateToken(bytes int) string {
	b := make([]byte, bytes)
	_, _ = rand.Read(b)
	return hex.EncodeToString(b)
}

func main() {
	// 32 字节 -> 64 位十六进制字符
	fmt.Println(onboardGenerateToken(32))
}

输出示例:

9d4f1a2b8c6e3f0d5a7b9c1e4f2d6a8b0c3e5f7d9a1b3c5e7f2d4a6b8c0e2f4d

注意:这里使用的是 crypto/rand(密码学安全)而非 math/rand(伪随机),生成 Token、密钥等安全敏感场景必须使用前者。

可逆编码:用 XXTEA 加密 + base64 输出

上一节的 hex.EncodeToString 是「把随机字节变成字符串」,属于单向展示。如果你想把一个整数 ID 编码成一段不可读、但还能还原回来的字符串(比如新闻 ID、用户 ID 放到 URL 里又不想暴露真实序号),可以走「XXTEA 对称加密 + base64 URL 安全编码」这条路。

package main

import (
	"encoding/base64"
	"fmt"
	"strconv"

	"github.com/xxtea/xxtea-go/xxtea"
)

var CryptoNormalKey = []byte("XXXXXX")

// Example 演示一次加密后再解密,应当原样还原
func Example(str string, key []byte) {
	encrypt_data := EncryptXXTEA(str, key)
	decrypt_data := DecryptXXTEA(encrypt_data, key)
	if str == string(decrypt_data) {
		fmt.Println("success!")
	} else {
		fmt.Println("fail!")
	}
}

func EncryptXXTEA(str string, key []byte) []byte {
	return xxtea.Encrypt([]byte(str), key)
}

func DecryptXXTEA(ciphertext []byte, key []byte) []byte {
	return xxtea.Decrypt(ciphertext, key)
}

// EncodeNewsId 把一个 int64 新闻 ID 编码成不可逆读、但可还原的 base64 字符串
func EncodeNewsId(newsId int64) string {
	if newsId == 0 {
		return ""
	}
	return base64.URLEncoding.EncodeToString(
		EncryptXXTEA(strconv.FormatInt(newsId, 10), CryptoNormalKey),
	)
}

要点:

  • xxtea.Encrypt / xxtea.Decrypt 都是 ([]byte, []byte) []byte,加解密用同一把 key(示例里是 CryptoNormalKey,实际请放到配置里,别硬编码)。
  • strconv.FormatInt(newsId, 10) 先把数字转成十进制字符串,再交给 XXTEA 加密,最后用 base64.URLEncoding 编码成可放进 URL 的字符串(不含 +、/ 这类会破坏 URL 的字符)。
  • 这是可逆的:拿到密文后 base64.URLDecode + xxtea.Decrypt 就能拿回原始 ID。它和前面 hex Token 的区别是——Token 是「随机值不可还原」,这里 ID 是「确定值可还原」。
  • ⚠️ 别把这当成真正的安全加密:密钥写在代码里、XXTEA 也非强加密算法,它只适合做「混淆 / 不暴露顺序」,不能用于保护敏感数据。

依赖:go get github.com/xxtea/xxtea-go/xxtea。