Вопрос

В настоящее время я генерирую 8-символьную псевдослучайную строку верхнего регистра для «A»..«З»:

value = ""; 8.times{value  << (65 + rand(25)).chr}

но он не выглядит чистым, и его нельзя передать в качестве аргумента, поскольку это не один оператор.Чтобы получить строку со смешанным регистром "a" .."з" плюс "А".."Z", я изменил его на:

value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr}

но это похоже на мусор.

Есть ли у кого-нибудь лучший метод?

Это было полезно?

Решение

(0...8).map { (65 + rand(26)).chr }.join

Я провожу слишком много времени за игрой в гольф.

(0...50).map { ('a'..'z').to_a[rand(26)] }.join

И последний, который еще более запутан, но более гибок и требует меньше циклов:

o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join

Другие советы

Почему бы не использовать SecureRandom?

require 'securerandom'
random_string = SecureRandom.hex

# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)

SecureRandom также имеет методы для:

  • база64
  • случайные_байты
  • случайное число

видеть: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html

Я использую это для генерации случайных строк, удобных для URL-адресов, с гарантированной максимальной длиной:

rand(36**length).to_s(36)

Он генерирует случайные строки строчных букв a-z и 0-9.Он не очень настраиваемый, но короткий и понятный.

Это решение генерирует строку легко читаемых символов для кодов активации;Я не хотел, чтобы люди путали 8 с B, 1 с I, 0 с O, L с 1 и т. д.

# Generates a random string from a set of easily readable characters
def generate_activation_code(size = 6)
  charset = %w{ 2 3 4 6 7 9 A C D E F G H J K M N P Q R T V W X Y Z}
  (0...size).map{ charset.to_a[rand(charset.size)] }.join
end

Другие упоминали нечто подобное, но здесь используется функция безопасного URL-адреса.

require 'securerandom'
p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="

Результат может содержать A-Z, a-z, 0-9, «-» и «_».«=» также используется, если заполнение истинно.

[*('A'..'Z')].sample(8).join

Создайте случайную строку из 8 букв (например,НВАЙXHGR)

([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(8).join

Создайте случайную строку из 8 символов (например,3PH4SWF2), исключает 0/1/I/O.Рубин 1.9

Поскольку с Ruby 2.5 действительно легко SecureRandom.alphanumeric:

len = 8
SecureRandom.alphanumeric(len)
=> "larHSsgL"

Генерирует случайные строки, содержащие A-Z, a-z и 0-9, поэтому их следует применять в большинстве случаев использования.И они генерируются случайным образом и безопасно, что тоже может быть преимуществом.


Редактировать:Тест для сравнения с решением, получившим наибольшее количество голосов:

require 'benchmark'
require 'securerandom'

len = 10
n = 100_000

Benchmark.bm(12) do |x|
  x.report('SecureRandom') { n.times { SecureRandom.alphanumeric(len) } }
  x.report('rand') do
    o = [('a'..'z'), ('A'..'Z'), (0..9)].map(&:to_a).flatten
    n.times { (0...len).map { o[rand(o.length)] }.join }
  end
end

                   user     system      total        real
SecureRandom   0.429442   0.002746   0.432188 (  0.432705)
rand           0.306650   0.000716   0.307366 (  0.307745)

Итак rand решение занимает всего около 3/4 времени SecureRandom.Это может иметь значение, если вы генерируете действительно много строк, но если вы просто время от времени создаете какую-то случайную строку, я бы всегда выбрал более безопасную реализацию (поскольку ее также проще вызывать и она более явна).

Я не могу вспомнить, где я это нашел, но мне кажется, что это лучший и наименее трудоемкий вариант:

def random_string(length=10)
  chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
  password = ''
  length.times { password << chars[rand(chars.size)] }
  password
end
require 'securerandom'
SecureRandom.urlsafe_base64(9)

Если вам нужна строка указанной длины, используйте:

require 'securerandom'
randomstring = SecureRandom.hex(n)

Он сгенерирует случайную строку длины 2n содержащий 0-9 и a-f

Array.new(n){[*"0".."9"].sample}.join, где n = 8 в вашем случае.

Обобщенный: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join, и т. д.- от этот отвечать

require 'sha1'
srand
seed = "--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]

Вот простой однострочный код для случайной строки длиной 8

 random_string = ('0'..'z').to_a.shuffle.first(8).join

Вы также можете использовать его для случайного пароля длиной 8.

random_password = ('0'..'z').to_a.shuffle.first(8).join

Я надеюсь, что это поможет и удивительно.

Руби 1.9+:

ALPHABET = ('a'..'z').to_a
#=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

10.times.map { ALPHABET.sample }.join
#=> "stkbssowre"

# or

10.times.inject('') { |s| s + ALPHABET.sample }
#=> "fdgvacnxhc"

Вот один простой код для случайного пароля длиной 8.

rand_password=('0'..'z').to_a.shuffle.first(8).join

Надеюсь, это поможет.

Имейте в виду: rand предсказуем для злоумышленника и, следовательно, вероятно, небезопасен.Вам обязательно следует использовать SecureRandom, если это необходимо для генерации паролей.Я использую что-то вроде этого:

length = 10
characters = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a

password = SecureRandom.random_bytes(length).each_char.map do |char|
  characters[(char.ord % characters.length)]
end.join

Еще один метод, который я люблю использовать

 rand(2**256).to_s(36)[0..7]

Добавьте lтолько, если вы действительно параноики по поводу правильной длины строки:

 rand(2**256).to_s(36).ljust(8,'a')[0..7]
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')

Что-то из Девайса

Я думаю, что это хороший баланс краткости, ясности и простоты модификации.

characters = ('a'..'z').to_a + ('A'..'Z').to_a
# Prior to 1.9, use .choice, not .sample
(0..8).map{characters.sample}.join

Легко модифицируется

Например, включая цифры:

characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a

Заглавные шестнадцатеричные числа:

characters = ('A'..'F').to_a + (0..9).to_a

Для действительно впечатляющего набора персонажей:

characters = (32..126).to_a.pack('U*').chars.to_a

Просто добавляю сюда свои центы...

def random_string(length = 8)
  rand(32**length).to_s(32)
end

вы можете использовать String#random из граней рубинового камня facets:

https://github.com/rubyworks/facets/blob/126a619fd766bc45588cac18d09c4f1927538e33/lib/core/facets/string/random.rb

в основном он делает это:

class String
  def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"])
    characters = character_set.map { |i| i.to_a }.flatten
    characters_len = characters.length
    (0...len).map{ characters[rand(characters_len)] }.join
  end
end

Мой любимый (:A..:Z).to_a.shuffle[0,8].join.Обратите внимание, что для перемешивания требуется Ruby > 1.9.

Это решение требует внешней зависимости, но кажется красивее другого.

  1. Установить драгоценный камень мошенник
  2. Faker::Lorem.characters(10) # => "ang9cbhoa8"

Данный:

chars = [*('a'..'z'),*('0'..'9')].flatten

Одно выражение, которое можно передать в качестве аргумента, допускает дублирование символов:

Array.new(len) { chars.sample }.join

Недавно я делал что-то подобное, чтобы сгенерировать 8-байтовую случайную строку из 62 символов.Символы были 0-9,a-z,A-Z.У меня был их массив, который выполнялся 8 раз и выбирал случайное значение из массива.Это было внутри приложения Rails.

str = '' 8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }

Странно то, что у меня много дубликатов.Теперь случайно это практически никогда не должно происходить.62^8 — это огромно, но из примерно 1200 кодов в базе данных у меня было большое количество дубликатов.Я заметил, что они происходят с разницей в несколько часов.Другими словами, я мог бы увидеть дубль в 12:12:23 и 2:12:22 или что-то в этом роде... не уверен, проблема во времени или нет.

Этот код использовался до создания объекта activerecord.Прежде чем запись была создана, этот код запускался и генерировал «уникальный» код.Записи в базе данных всегда создавались надежно, но код (str в строке выше) дублировался слишком часто.

Я создал сценарий для выполнения 100 000 итераций этой строки с небольшой задержкой, поэтому это заняло 3-4 часа, надеясь увидеть какой-то повторяющийся шаблон ежечасно, но ничего не увидел.Я понятия не имею, почему это происходило в моем приложении Rails.

''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }

Мои 2 цента:

  def token(length=16)
    chars = [*('A'..'Z'), *('a'..'z'), *(0..9)]
    (0..length).map {chars.sample}.join
  end

Я просто пишу маленькую жемчужину random_token чтобы генерировать случайные токены для большинства случаев использования, наслаждайтесь ~

https://github.com/sibevin/random_token

С помощью этого метода вы можете передать произвольную длину.По умолчанию установлено значение 6.

def generate_random_string(length=6)
  string = ""
  chars = ("A".."Z").to_a
  length.times do
    string << chars[rand(chars.length-1)]
  end
  string
end

Я думаю, мне больше всего нравится ответ Радара.Я бы немного подправил так:

CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
  s=''
  length.times{ s << CHARS[rand(CHARS.length)] }
  s
end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top