Создание руководств в Ruby

146

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

В частности, для рабочего процесса сброса пароля я хотел бы отправить токен Guid на электронную почту пользователя и попросить их сбросить свой пароль с помощью токена. Поскольку руководства уникальны, это довольно безопасно и избавляет меня от отправки паролей по электронной почте, что является рискованным.

Я заметил, что для Ruby есть один гем Guid ; но он выглядит довольно старым и записывает данные в файловую систему.

Кто-нибудь знает какие-нибудь другие драгоценные камни, которые могут создать глобальный уникальный идентификатор?

Я знаю, что могу просто вернуться к:

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

Но на самом деле это не похоже на правильный GUID ...

Сэм Шафран
источник
1
Было бы неправильно использовать такую ​​случайную строку; определенные биты в UUID определяют вариант и версию. Для случайного UUID вам, вероятно, понадобится вариант 2 (RFC 4122) и версия 4, и в этом случае 6 определенных битов должны быть установлены на правильные значения.
jtpereyda 05
1
Да, @dafrazzman прав. Случайное объединение чего-то, что «напоминает UUID», не гарантирует уникальности. Хотя на самом деле ни один UUID не гарантирован, построение одного со случайными числами намного более подвержено коллизиям и не может быть достойным ярлыка «UUID». Обязательно используйте SecureRandom.uuid!
dooleyo

Ответы:

322

Начиная с Ruby 1.9, генерация uuid встроена. Используйте SecureRandom.uuidфункцию.

Например:

require 'securerandom'
SecureRandom.uuid # => "96b0a57c-d9ae-453f-b56f-3b154eb10cda"
J _
источник
5
SecureRandom.uuid генерирует случайный UUID, поэтому его уникальность не гарантируется. Если вам просто нужна случайная строка, которая, вероятно, уникальна, можно использовать ее. Однако, если вы хотите что-то, что гарантированно будет уникальным, вам нужно будет использовать что-то, что включает в себя MAC-адрес, временную метку и т. Д.
Майк Доттерер
24
Чтобы сэкономить время на поиске, вам потребуется «securerandom»
Джесси Ши
8
Не гарантируется, что он будет уникальным, но для большинства практических целей можно с уверенностью предположить, что он уникален. См .: stackoverflow.com/questions/2977593/…
Джесси Ши
1
если SecureRandom.uuid соответствует RFC 4122, как сказано в документации, не означает ли это, что у него есть поле временной метки? Запрет параллелизма, разве это не означает уникальность?
Майкл К. Мэдисон
@MichaelKMadison AFAIK Ruby использует вариант RFC 4122 "v4", в котором не используется временная метка, поэтому вероятность столкновения на самом деле не равна нулю - но на практике она может быть такой же
Эдд Морган
35

Мы используем UUIDTools и никаких проблем с этим не имеем.

Авди
источник
2
uuidtools работает, даже если у системы нет MAC-адреса. uuid в этом случае не работает.
grefab
3
В отличие от гема uuid, uuidtools не хранит файл состояния. Проблемы с разрешениями в файле состояния делают гем uuid несколько неудобным для использования несколькими пользователями.
Уэйн Конрад
1
Похоже, что UUID Tools больше не поддерживается. За последние 2 года не было никаких обязательств по репозиторию github
Судханшу Мишра
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.

(Подсказка: я искал guid ruby в Google )

Марк В
источник
спасибо, я видел это, но он очень старый, просто ищу что-то активное, например, недавний драгоценный камень?
Лэнс Поллард,
Как насчет драгоценного камня uuid, который я добавил в свой ответ? Или это то, о чем вы говорили?
Marc W
5
Это странно ... Я тоже погуглил "guid ruby", и все, что я получил, это ТАК сообщение :-P
Джейсон Уайтхорн
3

Чтобы создать правильный GUID mysql, varchar 32

SecureRandom.uuid.gsub('-','').upcase
Аарон Хендерсон
источник
ИлиSecureRandom.hex.upcase
Даниэль Антонио Нуньес Каруайо
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
Надеюсь, вы не забыли проиндексировать свою колонку в ту ночь
nurettin
0

Когда я использовал гемы uuid, рекомендованные в этом вопросе, никто не мог сгенерировать уникальный и случайный UUID. Мой ответ - обходной путь: если позже у нас будет гем для удовлетворения запроса, лучше использовать гем в Ruby.

В этом вопросе я пробую большинство рекомендуемых драгоценных камней uuid, но меня никто не удовлетворяет, нам нужны уникальные и случайные uuid. Я напрямую запускаю системную команду uuidgenв ruby, и мне нравится результат, и я делюсь здесь.

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
И @J_, и @ 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
Санкарн
источник