Ruby'de Rehberler Oluşturma


142

Rehberler ile kolayca çözülebilecek bir sorunum var.

Özellikle, bir parola sıfırlama iş akışı için, bir kullanıcının e-postasına bir Guid token göndermek ve jetonu kullanarak parolalarını sıfırlamasını istiyorum. Rehberler benzersiz olduğu için, bu oldukça güvenlidir ve bana insanların şifrelerini e-posta ile göndermekten kurtarır, bu da risklidir.

Ruby için bir Guid mücevher olduğunu fark ettim ; ancak oldukça eski görünüyor ve dosya sistemine bir şeyler yazıyor.

Küresel olarak benzersiz bir tanımlayıcı oluşturabilen başka mücevherler bilen var mı?

Geri dönebileceğimi biliyorum:

(0..16).to_a.map{|a| rand(16).to_s(16)}.join 

Ama gerçekten uygun bir GUID gibi görünmüyor ...


1
Bunun gibi rastgele bir dize kullanmak tam olarak doğru olmaz; UUID'deki belirli bitler varyant ve sürümü belirtir. Rasgele bir UUID için, muhtemelen varyant 2 (RFC 4122) ve sürüm 4'ü istersiniz, bu durumda 6 belirli bitin doğru değerlere ayarlanması gerekir.
jtpereyda

1
Evet @dafrazzman haklı. "Bir UUID'ye benzeyen" bir şeyi rastgele bir şekilde birleştirmek benzersizliği garanti etmez. Hiçbir UUID gerçekten garanti edilmese de , rastgele sayılarla bir tane oluşturmak çarpışmalara karşı daha hassastır ve "UUID" etiketine layık değildir. Kesinlikle SecureRandom.uuid ile gidin!
dooleyo

Yanıtlar:


312

Ruby 1.9'dan itibaren, uuid üretimi yerleşiktir. SecureRandom.uuidİşlevi kullanın .

Örneğin:

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

5
SecureRandom.uuid rastgele bir UUID oluşturur, bu nedenle benzersiz olarak garanti edilmez. Sadece benzersiz olan rastgele bir dize istiyorsanız, bunu kullanmak uygun olacaktır. Ancak, benzersiz olduğu garanti edilen bir şey istiyorsanız, MAC adresini, zaman damgasını ve et cetera'yı içeren bir şey kullanmanız gerekecektir.
Mike Dotterer

23
Biraz arama yapmak için, 'güvenli' gereksiniminiz olacak
Jesse

8
Benzersiz olduğu garanti edilmez, ancak çoğu pratik amaç için benzersiz olduğunu varsaymak güvenlidir. Bakınız: stackoverflow.com/questions/2977593/…
Jesse Shieh

SecureRandom.uuid belgelere göre RFC 4122'yi izleyin, bu bir zaman damgası alanı olduğu anlamına gelmez mi? Eşzamanlılığı engellemek, bu benzersiz değil mi?
Michael K Madison

@MichaelKMadison AFAIK Ruby, zaman damgası kullanmayan RFC 4122'nin "v4" varyantını kullanıyor, bu yüzden çarpışma şansı aslında sıfır değil - ama pratikte de olabilir
Edd Morgan


35

Biz kullanmak UUIDTools ve onunla sorunumuz yok.


2
'uuidtools', sistemin MAC adresi olmasa bile çalışır. 'uuid' bu durumda başarısız olur.
grefab

3
Uuid gem aksine, uuidtools hiçbir durum dosyası tutar. Durum dosyasıyla ilgili izin sorunları, uuid gemini birden fazla kullanıcıyla kullanmak için biraz garip hale getirir.
Wayne Conrad

1
Artık UUID Araçları'nın bakımı yapılmadığı anlaşılıyor. 2 yıldan fazla bir süredir github repo için herhangi bir taahhütte bulunulmamış
Sudhanshu Mishra

22

Eğer baktın mı UUIDTools ?

UUIDTools, çeşitli UUID türlerinden (veya bunları çağırmayı tercih ederseniz GUID'lerden) herhangi birini oluşturmak için basit bir kütüphane olacak şekilde tasarlanmıştır. Mümkün olduğunda RFC 4122'ye uygundur.


16

Google şu Ruby kütüphanesini verir:

http://raa.ruby-lang.org/project/ruby-guid/

Ayrıca, http://www.ruby-forum.com/topic/99262 adresinden bir mücevher yükleyebileceğinizi (yüklemek gem uuidiçin komut satırında yürütebileceğinizi ) ve sonra

gem 'uuid'
puts UUID.new

yeni bir UUID görmek için kodunuzda.

(İpucu: Ben kılavuz yakut için googled )


thx Bunu gördüm ama son zamanlarda bir mücevher gibi aktif bir şey mi arıyorsunuz, çok eski mi?
Lance Pollard

Cevabıma eklediğim uuid gemine ne dersin? Yoksa bahsettiğiniz kişi mi?
Marc W

5
Bu garip ... Ben de "guid ruby" googled, ve tüm bu SO yazı oldu :-P
Jason Whitehorn


3

Simone Carletti'nin cevabı için küçük güncelleme:

SecureRandom.base64 (8) .gsub ( "/", "_"). Gsub (/ = + $ /, "")

=> "AEWQyovNFo0"

ile değiştirilebilir:

SecureRandom.urlsafe_base64 (8)


1

Gece geç saatlerde programlama yaparken, Rails'te benzersiz bir GUID oluşturmak için aşağıdaki çözümü (Simone'a dayanarak) buldum. Bununla gurur duymuyorum ama gayet iyi çalışıyor.

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

2
Umarım o gece rehber sütununu dizine eklemeyi hatırlarsın
nurettin

0

Bu soruda önerilen uuid taşlar kullandığımda, hiç kimse benzersiz ve rastgele UUID üretemez. Cevabım bir çözüm, daha sonra isteği karşılamak için mücevher varsa, Ruby'de mücevher kullanmak daha iyi olur.

Bu soruda en çok önerilen uuid mücevherleri deniyorum, ama kimse beni tatmin etmiyor, benzersiz ve rastgele uuid'e ihtiyacımız var. Doğrudan sistem komutunu uuidgenruby'de çalıştırıyorum ve sonucu beğendim ve burada paylaşıyorum.

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

uuidgem ile karşılaştırırsanız , farkı bileceksiniz.

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

Test ortamı linux ve Mac OS ortamıdır.


2
a puts `...`temelde uuidgen(3)Linux dışındaki herhangi bir platformda başarısız olan, aşırı miktarda yürütme süresi ekleyen ve genel olarak gerçekten sezgisel kodlama uygulaması olan bir sistem çağrısı yapıyor . Neden böyle bir yöntem seçesiniz ki?
Dwight Spencer

1
@DwightSpencer Sanırım farklı amaçlarla farklı bir alandayız. Yaptığınız şey, yürütme zamanı, geniş işletim sistemleri, kod geçişleri gibi endişelerimde değil. Kodun Mac OS veya ana akış Linux'ta çalışabileceğini ve ihtiyacım olan doğru sonucu elde edebileceğini umuyorum. Elbette, Ruby'de bir yol bulup uuidgen komutuyla aynı sonucu elde ederseniz, kullanmaktan mutluluk duyarım. Ama şimdiye kadar hiç bulamadım.
BMW

1
Hem @J_ hem de @ simone-carletti bu yayına daha iyi bir yol gösterdi. Ben biri SecureRandomiçin aynı yöntemle aynı işlevi önceden şekillendiren uuidgenama ben uuidgenengelleme / dev / random kullanımı aksine sadece SecureRandomönce openssl kütüphane kullanır sonra dev / urandom sonra nihayet / dev / random yapmak için önerir bloke olmayan randomizasyon üretimi.
Dwight Spencer

0

Bu JavaScript'ten öğrendiğim neet tekniği:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[rand(36)]
    end
end

Daha 'yakut' bir şekilde de yapılabilir:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        rand(16).to_s(16)
    end
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.