Створення посібників у Ruby


142

У мене є проблема, яку справді легко вирішити за допомогою Guids.

Зокрема, для робочого процесу скидання пароля я хотів би надіслати маркер Guid на електронну пошту користувача і змусити їх скинути свій пароль за допомогою маркера. Оскільки посібники унікальні, це досить безпечно і економить мені електронні листи паролів, що ризиковано.

Я помітив, що є одна дорогоцінна дорогоцінний камінь для Рубі; але він виглядає досить старим, і він записує матеріали до файлової системи.

Хтось знає про будь-які інші дорогоцінні камені, які можуть створити глобальний унікальний ідентифікатор?

Я знаю, що можу просто повернутися до:

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

Але це насправді не здається належним GUID ...


1
Використовувати подібний рядок як би це було б не зовсім правильно; певні біти UUID вказують варіант та версію. Для випадкового UUID, ймовірно, потрібно варіант 2 (RFC 4122) та версія 4, в цьому випадку 6 певних біт повинні бути встановлені на потрібні значення.
jtpereyda

1
Так @dafrazzman має рацію. Випадково з’єднання разом щось, що "нагадує UUID", не гарантує унікальності. Хоча жоден UUID не гарантується по-справжньому , побудова одного з випадковими числами є ДОПОЛОГО більш сприйнятливим до зіткнень і не може бути гідним етикетки "UUID". Однозначно йдіть із SecureRandom.uuid!
dooleyo

Відповіді:


312

Станом на Ruby 1.9 вбудована uuid-генерація. Використовуйте SecureRandom.uuidфункцію.

Наприклад:

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

5
SecureRandom.uuid генерує випадковий UUID, тому він не гарантується як унікальний. Якщо ви просто хочете випадкову рядок, який, ймовірно, унікальний, буде добре використовувати це. Однак, якщо вам потрібно щось унікальне, вам потрібно використовувати щось, що включає MAC-адресу, часову позначку та ін.
Майк Доттерер

23
Щоб заощадити трохи пошуку, вам потрібно буде вимагати "securerandom"
Jesse Shieh

8
Це не гарантовано, що він буде унікальним, але для більшості практичних цілей можна з упевненістю вважати, що він унікальний. Див: stackoverflow.com/questions/2977593 / ...
Джессі СІЕ

якщо SecureRandom.uuid дотримується RFC 4122, як написано згідно документації, чи це не означає, що в ньому є поле часової позначки? Якщо це не означає одночасність, чи це не означає унікальність?
Майкл К Медісон

@MichaelKMadison AFAIK Ruby використовує "v4" варіант RFC 4122, який не використовує часову позначку, тому шанс зіткнення насправді не нульовий - але на практиці це може бути
Едд Морган


35

Ми використовуємо UUIDTools і не маємо проблем з цим.


2
'uuidtools' працює, навіть коли система не має MAC-адреси. У цьому випадку "uuid" не вдається.
grefab

3
На відміну від самоцвіту uuid, uuidtools не зберігає жодного файлу стану. Проблеми з дозволом у файлі стану роблять uuid дорогоцінний камінь дещо незручним для використання з кількома користувачами.
Уейн Конрад

1
Схоже, інструменти UUID більше не підтримуються. Більше 2 років не було жодних зобов'язань щодо рефінансування github
Sudhanshu Mishra

22

Ви подивилися на UUIDTools ?

UUIDTools був розроблений як проста бібліотека для генерації будь-якого з різних типів UUID (або GUID, якщо ви вважаєте за краще їх називати). Він відповідає стандарту RFC 4122, коли це можливо.


16

Google видає таку бібліотеку Ruby:

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

Крім того, на веб- сайті http://www.ruby-forum.com/topic/99262 вони кажуть, що ви можете встановити дорогоцінний камінь (виконати gem uuidв командному рядку, щоб встановити його), а потім зробити

gem 'uuid'
puts UUID.new

у своєму коді, щоб побачити новий UUID.

(Підказка: Я гугла для рубіну гіда )


THX Я це бачив, але це дуже старе, просто шукаю щось активне, як-от недавній дорогоцінний камінь?
Ленс Поллард

Як щодо ювелірного каменя, який я додав до своєї відповіді? Або це той, про кого ви мали на увазі?
Marc W

5
Це дивно ... Я також гуглив "Рубін рубін", і все, що я отримав, це ТАК повідомлення :-P
Джейсон Уайтхорн


3

Невелике оновлення відповіді Сімоне Карлетті:

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

=> "AEWQyovNFo0"

можна замінити на:

SecureRandom.urlsafe_base64 (8)


1

Під час програмування пізно вночі я придумав таке рішення (засноване від Simone's) для створення унікального GUID в Rails. Я не пишаюся цим, але це працює досить добре.

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

2
Я сподіваюся, що ви згадали про те, щоб продемонструвати свою колонку гіда тієї ночі
Нуреттін

0

Коли я використовував уеідні дорогоцінні камені, рекомендовані в цьому питанні, ніхто не може створити унікальний і випадковий UUID. Моя відповідь - це вирішення проблеми, якщо пізніше у нас з'явиться дорогоцінний камінь, щоб задовольнити запит, то краще використовувати дорогоцінний камінь у Ruby.

Я намагаюся в цьому питанні найбільш рекомендовані дорогоцінні камені uuid, але мене ніхто не влаштовує, нам потрібен унікальний і випадковий uuid. Я безпосередньо запускаю системну команду 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дорогоцінним каменем, ви дізнаєтесь різницю.

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.


2
a, puts `...`в основному, робить системний виклик, uuidgen(3)який виходить з ладу на будь-якій іншій платформі, окрім Linux, додає надзвичайну кількість часу на виконання, і взагалі дійсно протидіє практиці інтуїтивного кодування. Чому ви обираєте такий метод?
Дуайт Спенсер

1
@DwightSpencer Я думаю, що ми перебуваємо в різних областях з різною метою. Те, що вас хвилює, зовсім не викликає моїх проблем, таких як час виконання, широкий спектр операційних систем, міграція коду. Мені подобається, що код може працювати в Mac OS або в основному Linux і отримати потрібний потрібний результат. З іншого боку, якщо ви можете розібратися в Ruby і отримати такий же результат, як команда uuidgen, я з радістю використовую його. Але до цих пір я не знайшов жодного.
BMW

1
І JJ, і @ simone-carletti вже вказали на кращий шлях у цій посаді. Я б, наприклад, підказав SecureRandom, що це попередньо формує ту ж функцію тим самим методом, що, uuidgenале на відміну від uuidgenвикористання блокування / dev / random тільки SecureRandomспочатку використовує бібліотеку openssl, потім переходить до dev / urandom, а потім, нарешті, / dev / random у спробах зробити не блокує генерацію рандомізації.
Дуайт Спенсер

0

Це нейт-метод, який я навчився з JavaScript:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.