Golang如何生成随机符号字符串(已解答)

Golang如何生成随机符号字符串(已解答) 大家好。我之前创建了一个同名主题[1]但已删除。现在我将它连同答案一起重新发布在这里。

[1] 如何生成随机符号字符串

答案:

rand.Seed(time.Now().UnixNano())
digits := "0123456789"
specials := "~=+%^*/()[]{}/!@#$?|"
all := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
    "abcdefghijklmnopqrstuvwxyz" +
    digits + specials
length := 8
buf := make([]byte, length)
buf[0] = digits[rand.Intn(len(digits))]
buf[1] = specials[rand.Intn(len(specials))]
for i := 2; i < length; i++ {
    buf[i] = all[rand.Intn(len(all))]
}
rand.Shuffle(len(buf), func(i, j int) {
    buf[i], buf[j] = buf[j], buf[i]
})
str := string(buf)

来源:生成随机字符串(密码) · YourBasic Go

注:由于它们是ASCII字符,你还可以添加更多符号(例如 ´;:<> \" \\)(我在最后这些符号中加了斜杠,以便将它们“声明”为字符串而非属性。)


更多关于Golang如何生成随机符号字符串(已解答)的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang如何生成随机符号字符串(已解答)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个很好的随机字符串生成方案,特别适合生成包含特定字符类别的密码。不过从Go 1.20开始,rand.Seed已被弃用,建议使用rand.NewSource。以下是更新后的版本:

package main

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

func generateRandomString(length int) string {
	if length < 2 {
		length = 8
	}
	
	src := rand.NewSource(time.Now().UnixNano())
	r := rand.New(src)
	
	digits := "0123456789"
	specials := "~=+%^*/()[]{}/!@#$?|"
	all := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
		"abcdefghijklmnopqrstuvwxyz" +
		digits + specials
	
	buf := make([]byte, length)
	buf[0] = digits[r.Intn(len(digits))]
	buf[1] = specials[r.Intn(len(specials))]
	
	for i := 2; i < length; i++ {
		buf[i] = all[r.Intn(len(all))]
	}
	
	r.Shuffle(len(buf), func(i, j int) {
		buf[i], buf[j] = buf[j], buf[i]
	})
	
	return string(buf)
}

func main() {
	fmt.Println(generateRandomString(8))
	fmt.Println(generateRandomString(12))
}

如果需要更安全的加密随机数,可以使用crypto/rand

package main

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

func cryptoRandomString(length int) string {
	if length < 2 {
		length = 8
	}
	
	digits := "0123456789"
	specials := "~=+%^*/()[]{}/!@#$?|"
	all := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
		"abcdefghijklmnopqrstuvwxyz" +
		digits + specials
	
	buf := make([]byte, length)
	
	// 确保至少包含一个数字
	n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(digits))))
	buf[0] = digits[n.Int64()]
	
	// 确保至少包含一个特殊字符
	n, _ = rand.Int(rand.Reader, big.NewInt(int64(len(specials))))
	buf[1] = specials[n.Int64()]
	
	// 填充剩余位置
	for i := 2; i < length; i++ {
		n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(all))))
		buf[i] = all[n.Int64()]
	}
	
	// Fisher-Yates洗牌算法
	for i := len(buf) - 1; i > 0; i-- {
		j, _ := rand.Int(rand.Reader, big.NewInt(int64(i+1)))
		buf[i], buf[j.Int64()] = buf[j.Int64()], buf[i]
	}
	
	return string(buf)
}

func main() {
	fmt.Println(cryptoRandomString(8))
}
回到顶部