2009-07-13 3 views
97

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

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

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

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

Я знаю, что могу просто упасть обратно:

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

Но это не очень похоже, как настоящий GUID ...

+0

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

+1

Да @ dafrazzman прав. Случайно соединяя что-то, что «напоминает UUID», не гарантирует уникальности. Хотя UUID не гарантирован * *, построение одного со случайными числами FAR более восприимчиво к столкновениям и не может быть достойным метки «UUID». Определенно зайдите с SecureRandom.uuid! – dooleyo

ответ

207

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

Например:

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

SecureRandom.uuid генерирует случайный UUID, поэтому он не гарантируется как уникальный. Если вам просто нужна случайная строка, которая, вероятно, уникальна, это будет нормально использовать. Однако, если вы хотите, чтобы что-то было гарантировано уникальным, вам нужно будет использовать что-то, что включает в себя MAC-адрес, метку времени и т. Д. –

+20

Чтобы сохранить вас в поиске, вам понадобится require 'securerandom' –

+8

Не гарантируется уникальность, но для большинства практических целей можно с уверенностью предположить, что он уникален. См. Http://stackoverflow.com/questions/2977593/is-it-safe-to-assume-a-guid-will-always-be-unique –

20

ли вы смотреть на UUIDTools?

UUIDTools был разработан как простая библиотека для генерации любых типов UUID (или GUID, если вы предпочитаете их называть). Он соответствует RFC 4122, когда это возможно.

+0

nope не заметил это. Похоже, что он решает мою проблему. –

+0

Очень круто - надеюсь, что это трюк :) –

31

How to create small, unique tokens in Ruby

>> require 'digest' 
=> [] 
>> Digest::SHA1.hexdigest("some-random-string")[8..16] 
=> "2ebe5597f" 

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

>> rand(36**8).to_s(36) 
=> "uur0cj2h" 
+2

На этой странице есть много действительно классных решений. – Abel

+4

В случае, если кто-то захочет это посмотреть. [Wayback Machine] (http://web.archive.org/web/20120925034700/http://blog.logeek.fr/2009/7/2/creating-small-unique-tokens-in-ruby) – engineerDave

14

Google дает следующее Рубиновый библиотека:

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

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

gem 'uuid' 
puts UUID.new 

в вашем коде для просмотра нового UUID.

(Подсказка: Я Googled для Guid рубин)

+0

thx I видел это, но это супер старый, просто ищет что-то активное, как недавний камень? –

+2

Ничего плохого в старой библиотеке. –

+0

Как насчет жемчужины uuid, добавленных в мой ответ? Или это тот, о котором вы говорили? –

34

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

+2

«uuidtools» работает, даже если в системе нет MAC-адреса. В этом случае «uuid» терпит неудачу. – grefab

+3

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

+0

Похоже, что UUID Tools больше не поддерживается. Не было никаких обязательств по рефинансированию github за последние 2 года. – dotnetguy

1

Хотя программирование поздно ночью я придумал следующее решение (на основе от Симоне) для создания уникального идентификатора GUID в Rails. Я не горжусь этим, но он работает очень хорошо.

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

Надеюсь, вы вспомнили, что указали свой столбец в ту ночь – nurettin

1

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

SecureRandom.uuid.gsub('-','').upcase 
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.

+1

a 'puts \' ... \ '' в основном выполняет системный вызов 'uuidgen (3)', который не работает на любой другой платформе, отличной от Linux, добавляет чрезмерное количество времени выполнения и, в общем, действительно противоречит интуитивной практике кодирования. Почему вы выбрали такой метод? –

+1

@DwightSpencer Я думаю, что мы находимся в разных областях с разной целью. Все, что вас беспокоит, совсем не касается моих проблем, таких как время выполнения, широкий спектр операционных систем, миграция кода. Мне все равно, что код может работать в Mac OS или в основном потоке Linux и получить нужный мне результат. Если вы можете проработать путь в Ruby и получить тот же результат, что и команда uuidgen, я рад его использовать. Но до сих пор я не нашел. – BMW

+0

Оба @J_ и @ simone-carletti уже указали лучший способ на этом посту. Я хотел бы предложить «SecureRandom», поскольку он формирует одну и ту же функцию в том же методе, что и «uuidgen», но в отличие от «uuidgen» использования блокировки/dev/random только «SecureRandom» сначала использует библиотеку openssl, а затем падает на dev/urandom, затем finally/dev/random в попытках генерации не блокирующей рандомизации. –

2

Небольшое обновление для Simone Carletti ответ:.

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

=> "AEWQyovNFo0"

могут быть заменены:

SecureRandom.urlsafe_base64 (8)