Tạo hướng dẫn trong Ruby


142

Tôi có vấn đề thực sự dễ dàng giải quyết với Hướng dẫn.

Đặc biệt, đối với quy trình đặt lại mật khẩu, tôi muốn gửi mã thông báo Hướng dẫn đến email của người dùng và yêu cầu họ đặt lại mật khẩu bằng mã thông báo. Vì các hướng dẫn là duy nhất, điều này khá an toàn và giúp tôi gửi email mật khẩu cho mọi người, điều này rất rủi ro.

Tôi nhận thấy có một viên ngọc Guid cho Ruby; nhưng nó trông khá cũ và nó ghi công cụ vào hệ thống tập tin.

Có ai biết bất kỳ loại đá quý nào khác có thể tạo ra một định danh duy nhất trên toàn cầu không?

Tôi biết tôi chỉ có thể quay lại:

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

Nhưng nó không thực sự giống như một HƯỚNG DẪN đúng đắn ...


1
Sử dụng một chuỗi ngẫu nhiên như thế sẽ không hoàn toàn đúng; một số bit nhất định trong UUID chỉ định biến thể và phiên bản. Đối với một UUID ngẫu nhiên, bạn có thể muốn biến thể 2 (RFC 4122) và phiên bản 4, trong trường hợp đó, 6 bit nhất định phải được đặt thành đúng giá trị.
jtpereyda

1
Có @dafrazzman là đúng. Ngẫu nhiên ghép lại một cái gì đó "giống với UUID" không đảm bảo tính duy nhất. Mặc dù không có UUID nào thực sự được đảm bảo, nhưng việc xây dựng một số có số ngẫu nhiên là FAR dễ bị va chạm hơn và không thể xứng đáng với nhãn "UUID". Chắc chắn đi với SecureRandom.uuid!
dooleyo

Câu trả lời:


312

Kể từ Ruby 1.9, thế hệ uuid được tích hợp sẵn. Sử dụng SecureRandom.uuidchức năng.

Ví dụ:

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

5
SecureRandom.uuid tạo ra một UUID ngẫu nhiên, vì vậy nó không được đảm bảo là duy nhất. Nếu bạn chỉ muốn một chuỗi ngẫu nhiên có lẽ là duy nhất thì sẽ ổn khi sử dụng chuỗi này. Tuy nhiên, nếu bạn muốn một cái gì đó được đảm bảo là duy nhất, bạn sẽ cần sử dụng thứ gì đó bao gồm địa chỉ MAC, dấu thời gian và et cetera.
Mike Dotterer

23
Để tiết kiệm cho bạn một chút tra cứu, bạn sẽ cần phải có 'người bảo mật'
Jesse Shieh

8
Nó không được đảm bảo là duy nhất, nhưng đối với hầu hết các mục đích thực tế, sẽ an toàn khi cho rằng nó là duy nhất. Xem: stackoverflow.com/questions/2977593/
Mạnh

nếu SecureRandom.uuid tuân theo RFC 4122 như đã nói theo tài liệu, điều đó có nghĩa là nó có trường dấu thời gian không? Chặn đồng thời, không có nghĩa là duy nhất?
Michael K Madison

@MichaelKMadison AFAIK Ruby sử dụng biến thể "v4" của RFC 4122, không sử dụng dấu thời gian, do đó, khả năng va chạm không thực sự là không - nhưng thực tế nó cũng có thể
Edd Morgan


35

Chúng tôi sử dụng UUIDTools và không có vấn đề gì với nó.


2
'uuidtools' hoạt động, ngay cả khi hệ thống không có địa chỉ MAC. 'uuid' thất bại trong trường hợp này.
grefab

3
Không giống như đá quý uuid, uuidtools không giữ tệp trạng thái. Các vấn đề về quyền với tệp trạng thái làm cho viên ngọc uuid hơi khó sử dụng với nhiều người dùng.
Wayne Conrad

1
Dường như Công cụ UUID không được duy trì nữa. Không có bất kỳ cam kết nào với repo github trong hơn 2 năm
Sudhanshu Mishra

22

Bạn đã nhìn vào UUIDTools ?

UUIDTools được thiết kế để trở thành một thư viện đơn giản để tạo bất kỳ loại UUID nào khác (hoặc GUID nếu bạn muốn gọi chúng là như vậy). Nó phù hợp với RFC 4122 bất cứ khi nào có thể.


16

Google mang lại thư viện Ruby sau:

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

Ngoài ra, tại http://www.ruby-forum.com/topic/99262 họ nói rằng bạn có thể cài đặt một viên ngọc (thực hiện gem uuidtrên dòng lệnh để cài đặt nó) và sau đó làm

gem 'uuid'
puts UUID.new

trong mã của bạn để xem UUID mới.

(Gợi ý: Tôi đã tìm kiếm ruby hướng dẫn )


Tôi đã thấy điều đó nhưng nó đã quá cũ, chỉ tìm kiếm thứ gì đó hoạt động, như một viên ngọc gần đây?
Lance Pollard

Làm thế nào về đá quý uuid tôi thêm vào câu trả lời của tôi? Hay đó là người bạn đang đề cập đến?
Marc W

5
Đó là kỳ lạ ... Tôi cũng đã googled "hướng dẫn ruby", và tất cả những gì tôi nhận được là bài đăng SO này :-P
Jason Whitehorn


3

Cập nhật nhỏ cho câu trả lời của Simone Carletti:

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

=> "AEWQyovNFo0"

có thể được thay thế bằng:

SecureRandom.urlsafe_base64 (8)


1

Trong khi lập trình vào đêm khuya, tôi đã nghĩ ra giải pháp sau (dựa trên Simone) để tạo GUID duy nhất trong Rails. Tôi không tự hào về nó nhưng nó hoạt động khá tốt.

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

2
Tôi hy vọng bạn nhớ lập chỉ mục cột hướng dẫn của bạn tối hôm đó
Nurettin

0

Khi tôi sử dụng đá quý uuid được đề xuất trong câu hỏi này, không ai có thể tạo UUID duy nhất và ngẫu nhiên. Câu trả lời của tôi là một công việc xung quanh, nếu chúng ta có đá quý sau này để đáp ứng yêu cầu, tốt hơn là bạn nên sử dụng đá quý trong Ruby.

Tôi thử hầu hết các loại đá quý uuid được đề nghị trong câu hỏi này, nhưng không ai làm tôi hài lòng, chúng tôi cần uuid độc đáo và ngẫu nhiên. Tôi trực tiếp chạy lệnh hệ thống uuidgentrong ruby, và tôi thích kết quả này, và chia sẻ ở đây.

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

Nếu so sánh với uuidđá quý, bạn sẽ biết sự khác biệt.

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

Môi trường thử nghiệm là môi trường linux và Mac OS.


2
a puts `...`về cơ bản là thực hiện một cuộc gọi hệ thống uuidgen(3)mà không thành công trên bất kỳ nền tảng nào khác ngoài Linux, thêm thời lượng thực hiện cực lớn và nói chung là thực sự chống lại thực hành mã hóa trực quan. Tại sao bạn lại chọn một phương pháp như vậy?
Dwight Spencer

1
@DwightSpencer Tôi nghĩ rằng chúng tôi đang ở trong khu vực khác nhau với mục đích khác nhau. Những gì bạn quan tâm không phải là mối quan tâm của tôi, chẳng hạn như thời gian thực hiện, phạm vi rộng của các hệ thống hoạt động, di chuyển mã. Tôi quan tâm mã có thể hoạt động trong Mac OS hoặc Linux dòng chính và nhận được kết quả đúng mà tôi cần. Của couse, nếu bạn có thể tìm ra cách trong Ruby và nhận được kết quả tương tự như lệnh uuidgen, tôi rất vui khi sử dụng nó. Nhưng cho đến bây giờ, tôi đã không tìm thấy bất kỳ.
BMW

1
Cả @J_ và @ simone-carletti đều đã chỉ ra một cách tốt hơn cho bài đăng này. Tôi cho một người sẽ đề xuất SecureRandomrằng đó là tạo ra cùng một chức năng trong cùng một phương thức như uuidgennhưng không giống như uuidgenviệc sử dụng chặn / dev / ngẫu nhiên chỉ SecureRandomsử dụng thư viện openssl trước sau đó giảm xuống dev / urandom sau đó cuối cùng / dev / ngẫu nhiên để thử không chặn tạo ngẫu nhiên.
Dwight Spencer

0

Đây là một kỹ thuật neet tôi học được từ JavaScript:

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

Mặc dù theo cách 'ruby' hơn, người ta cũng có thể làm:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        rand(16).to_s(16)
    end
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.