为了账号安全,请及时绑定邮箱和手机立即绑定

我可以依靠 Go 的 `crypto/rand` 包给我唯一的随机字符串吗?

我可以依靠 Go 的 `crypto/rand` 包给我唯一的随机字符串吗?

Go
一只名叫tom的猫 2023-01-03 17:03:49
我想生成 32 个字符长的unique unguessable字母数字密钥。密钥将是我系统的标识符,将用于查找信息。在网上搜索时,我偶然发现crypto/rand了Go. 它能够在下划线系统调用的帮助下生成随机字母数字。但我担心crypto/rand包返回的值可能会产生一个非唯一的字符串。谁能澄清我是否可以依靠crypto/rand包裹来完成这项工作?
查看完整描述

3 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

当然,对于随机生成的令牌,始终存在生成重复令牌的可能性。有一些标准,例如UUID(不包括 v4)使用其他方法来尝试“保证”每个标识符的唯一性。这些方法并没有真正消除碰撞的可能性,它们只是改变了故障模式。例如,UUID1 依赖于MAC 地址的唯一性,这本身就是一个问题。

如果你不受令牌大小的限制,你可以很容易地选择足够多的比特,使得碰撞的概率变得如此之小,以至于与无数其他故障模式(例如程序员错误、宇宙射线、a大规模全球灭绝事件等)。

非常近似地,如果你有一个真正的 N 位随机密钥长度,你可以在有 50% 的机会看到冲突之前生成 2^(N/2) 个密钥。有关更通用的公式,请参阅UUID#Collisions的维基百科页面。


查看完整回答
反对 回复 2023-01-03
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

我认为,对于这类事情,你应该使用UUID

package main


import (

    "fmt"

    "github.com/google/uuid"

)


func main() {

    id := uuid.New()

    fmt.Println(id.String())

}


查看完整回答
反对 回复 2023-01-03
?
慕娘9325324

TA贡献1783条经验 获得超4个赞

对于 crypto/rand,不能保证单个随机数会多次出现。但是,发生这种情况的可能性非常低,并且对于您的用例来说可能已经足够好了。在许多情况下,UUID 就足够了。如果您对重复 UUID 的概率感到好奇,请参阅维基百科

如果您真的需要真正的唯一性,您可能希望将随机数与映射结合起来记录它们,其中数字作为键,值是“无关”。在记录数字时,可以检测到重复项,并可以请求新的随机数以防万一。但是,这种方法可能会带来新的挑战,具体取决于您的设置,因为数字现在保存在本身不安全的内存中。如果您的用例无法确定系统生命周期内所需的机密数量,那么它在复杂性方面也将具有挑战性。

对我来说,这实际上归结为一个问题,即您用于信息查找的系统标识符是否真的是秘密,或者您只想要在系统中出现之前难以预测的唯一标识符。也许您可以详细说明您的用例以阐明您的要求。


查看完整回答
反对 回复 2023-01-03
  • 3 回答
  • 0 关注
  • 318 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信