在Ruby中生成guid

在Ruby中生成guid,ruby,guid,Ruby,Guid,我有一个用guid很容易解决的问题 特别是,对于密码重置工作流,我希望向用户的电子邮件发送GUID令牌,并让他们使用令牌重置密码。由于guid是唯一的,所以它非常安全,可以为我发送电子邮件节省密码,这是很危险的 我注意到有一个,但它看起来很旧,它会把东西写入文件系统 有人知道其他可以创建全局唯一标识符的gem吗 我知道我可以回到: (0..16).to|a.map{a|rand(16).to|s(16)}.join 但它看起来并不是一个合适的GUID…您看到了吗 UUIDTools被设计成一个

我有一个用guid很容易解决的问题

特别是,对于密码重置工作流,我希望向用户的电子邮件发送GUID令牌,并让他们使用令牌重置密码。由于guid是唯一的,所以它非常安全,可以为我发送电子邮件节省密码,这是很危险的

我注意到有一个,但它看起来很旧,它会把东西写入文件系统

有人知道其他可以创建全局唯一标识符的gem吗

我知道我可以回到:

(0..16).to|a.map{a|rand(16).to|s(16)}.join
但它看起来并不是一个合适的GUID…

您看到了吗

UUIDTools被设计成一个简单的库,用于生成各种类型的uuid(或者guid,如果您愿意这样称呼它们的话)。尽可能符合RFC 4122的要求


Google提供了以下Ruby库:

另外,他们说你可以安装一个gem(在命令行上执行
gemuuid
来安装它),然后

gem 'uuid'
puts UUID.new
在代码中查看新的UUID


(提示:我搜索了GuidRuby)

从Ruby1.9开始,uuid生成是内置的。使用该函数

例如:

require 'securerandom'
SecureRandom.uuid # => "96b0a57c-d9ae-453f-b56f-3b154eb10cda"

在深夜编程时,我提出了以下解决方案(基于Simone的),用于在Rails中生成唯一的GUID。我并不为它感到骄傲,但它确实工作得很好

while Order.find_by_guid(guid = rand(36**8).to_s(36).upcase).present?; end

要创建正确的、mysql、varchar 32 GUID

SecureRandom.uuid.gsub('-','').upcase
当我使用这个问题中推荐的uuid gems时,没有人可以生成唯一和随机的uuid。我的答案是一种变通方法,如果我们以后有gem来满足这个请求,那么最好在Ruby中使用gem

在这个问题上,我尝试了最推荐的uuid宝石,但没有人让我满意,我们需要唯一和随机的uuid。我直接在ruby中运行system命令
uuidgen
,我喜欢这个结果,并在这里分享

puts `uuidgen`
8adea17d-b918-43e0-b82f-f81b3029f688
puts `uuidgen`
6a4adcce-8f64-41eb-bd7e-e65ee6d11231
puts `uuidgen`
51d5348b-8fc3-4c44-a6f7-9a8588d7f08a
puts `uuidgen`
332a0fa3-7b07-41e1-9fc8-ef804a377e4e
如果与
uuid
gem进行比较,您将知道其中的区别

irb(main):003:0> uuid.generate
=> "40cdf890-ebf5-0132-2250-20c9d088be77"
irb(main):004:0> uuid.generate
=> "4161ac40-ebf5-0132-2250-20c9d088be77"

测试环境是linux和Mac OS环境。

对Simone Carletti的小更新回答:

SecureRandom.base64(8).gsub(“/”,“”).gsub(/=+$/,”)

=>“AEWQyovNFo0”

可替换为:

SecureRandom.urlsafe_base64(8)


这是我从JavaScript中学到的neet技巧:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[rand(36)]
    end
end
尽管以更“红宝石”的方式,我们也可以做到:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        rand(16).to_s(16)
    end
end

thx我看到了,但它非常古老,只是在寻找一些活跃的东西,比如最近的宝石?我在回答中添加的uuid宝石怎么样?还是你说的那个?那很奇怪。。。我也在谷歌上搜索了“guid ruby”,我得到的只是这篇S.O.帖子:-PSecureRandom.uuid会生成一个随机的uuid,所以不能保证它是唯一的。如果您只是想要一个可能是唯一的随机字符串,那么可以使用它。但是,如果您想要确保某个内容是唯一的,则需要使用包含MAC地址、时间戳等内容的内容。为了节省查找时间,您需要要求“securerandom”,它不保证是唯一的,但出于最实际的目的,可以安全地假定它是唯一的。请参阅:如果SecureRandom.uuid按照文档中的说明遵循RFC 4122,这不意味着它有一个时间戳字段吗?除非并发,否则这不意味着唯一吗?@MichaelKMadison AFAIK Ruby使用RFC 4122的“v4”变体,它不使用时间戳,因此冲突的可能性实际上不是零——但实际上,最好还是希望您记得那天晚上使用这样的随机字符串为guid列编制索引是不对的;UUID中的某些位指定变量和版本。对于随机UUID,您可能需要变体2(RFC4122)和版本4,在这种情况下,必须将6个特定位设置为正确的值。随机拼凑“类似UUID”的东西并不能保证唯一性。虽然没有UUID是真正有保证的,但构建一个随机数的UUID更容易受到冲突的影响,不值得使用“UUID”标签。一定要使用SecureRandom.uuid!一个
put```
基本上是对
uuidgen(3)
进行系统调用,这在除Linux以外的任何其他平台上都会失败,增加了大量的执行时间,并且通常是违反直觉的编码实践。“你为什么选择这样一种方法?”德怀特·斯宾塞我想我们在不同的领域,有着不同的目的。您关心的根本不是我关心的问题,例如执行时间、广泛的操作系统、代码迁移。我关心的代码可以在Mac OS或主流Linux中工作,并得到我需要的正确结果。当然,如果您能在Ruby中找到一种方法,并获得与uuidgen命令相同的结果,我很乐意使用它。但直到现在,我还没有找到任何答案。@J_u和@simone carletti已经在这篇文章中指出了更好的方法。例如,我建议使用
SecureRandom
,因为这是以与
uuidgen
相同的方法执行相同的功能,但与
uuidgen
不同的是,uuidgen使用blocking/dev/random only
SecureRandom
首先使用openssl库,然后将其放到dev/urandom中,最后尝试使用/dev/random来实现非阻塞随机化生成。或
SecureRandom.hex.upcase
def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        rand(16).to_s(16)
    end
end