Jak wygenerować losowy ciąg znaków w Ruby
Obecnie generuję 8-znakowy pseudolosowy ciąg wielkich liter dla "A".. "Z": {]}
value = ""; 8.times{value << (65 + rand(25)).chr}
Ale nie wygląda to na czyste i nie może być przekazane jako argument, ponieważ nie jest pojedynczą instrukcją. Aby uzyskać mieszany ciąg znaków "a".. "z" plus "A".. "Z", zmieniłem na:
value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr}
Ale wygląda jak śmieć.
Czy ktoś ma lepszą metodę? 30 answers
(0...8).map { (65 + rand(26)).chr }.join
Za dużo czasu spędzam na golfie.
(0...50).map { ('a'..'z').to_a[rand(26)] }.join
I ostatni, który jest jeszcze bardziej zagmatwany, ale bardziej elastyczny i marnuje mniej cykli:]}
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 10:56:00
Dlaczego nie użyć SecureRandom?
require 'securerandom'
random_string = SecureRandom.hex
# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)
SecureRandom ma również metody dla:
- base64
- random_bytes
- random_number
Zobacz: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-04 20:07:47
Używam tego do generowania losowych łańcuchów przyjaznych URL o gwarantowanej maksymalnej długości:
rand(36**length).to_s(36)
Generuje losowe ciągi małych liter a-z i 0-9. Nie jest zbyt konfigurowalny, ale jest krótki i czysty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-04 08:37:57
To rozwiązanie generuje ciąg łatwych do odczytania znaków dla kodów aktywacyjnych; nie chciałem, aby ludzie mylili 8 z B, 1 z I, 0 Z O, L z 1, itd.
# 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-25 00:32:31
Inni wspominali o czymś podobnym, ale używa To funkcji URL safe.
require 'securerandom'
p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
Wynik może zawierać A-Z, A-Z, 0-9, " - "i"_". "="jest również używany, jeśli wypełnienie jest prawdziwe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-16 19:40:12
[*('A'..'Z')].sample(8).join
Wygeneruj losowy ciąg 8 liter (np. NVAYXHGR)
([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(8).join
Wygenerować losowy ciąg 8 znaków (np. 3PH4SWF2), wyłączając 0/1/I/O. Ruby 1.9
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-22 11:58:53
Nie pamiętam, gdzie to znalazłem, ale wydaje mi się, że jest to najlepsze i najmniej intensywne procesowo:
def random_string(length=10)
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
password = ''
length.times { password << chars[rand(chars.size)] }
password
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-24 22:41:44
require 'securerandom'
SecureRandom.urlsafe_base64(9)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-13 00:34:57
Od ruby 2.5 naprawdę łatwo z SecureRandom.alphanumeric
:
len = 8
SecureRandom.alphanumeric(len)
=> "larHSsgL"
Generuje losowe łańcuchy zawierające A-Z, a-Z i 0-9 i dlatego powinny być stosowane w większości przypadków. I są one generowane losowo bezpieczne, co może być również korzyścią.
Edit: benchmark do porównania go z rozwiązaniem mającym najwięcej upvotes:
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)
Więc rozwiązanie rand
zajmuje tylko około 3/4 czasu SecureRandom
. Może mieć znaczenie, jeśli generujesz naprawdę dużo ciągów, ale jeśli wystarczy stworzyć jakiś losowy ciąg znaków od czasu do czasu zawsze wybierałbym bardziej bezpieczną implementację (ponieważ jest również łatwiejsze do wywołania i bardziej wyraźne).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-30 12:39:47
Jeśli chcesz ciąg o określonej długości, użyj:
require 'securerandom'
randomstring = SecureRandom.hex(n)
Wygeneruje losowy ciąg o długości 2n
zawierający 0-9
i a-f
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-15 09:28:29
Array.new(n){[*"0".."9"].sample}.join
,
gdzie n = 8 w Twoim przypadku.
Uogólnione: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
, itd. - from this answer
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:59
require 'sha1'
srand
seed = "--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 22:40:34
Oto jeden wiersz prosty kod dla losowego ciągu o długości 8
random_string = ('0'..'z').to_a.shuffle.first(8).join
Możesz również użyć go do losowego hasła o długości 8
random_password = ('0'..'z').to_a.shuffle.first(8).join
Mam nadzieję, że to pomoże i będzie niesamowite.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-19 06:12:15
Ruby 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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 15:04:26
Oto jeden prosty kod dla losowego hasła z lenth 8
rand_password=('0'..'z').to_a.shuffle.first(8).join
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-15 06:51:24
Bądź świadomy: rand
jest przewidywalny dla atakującego, a zatem prawdopodobnie niepewny. Zdecydowanie powinieneś użyć SecureRandom, jeśli jest to do generowania haseł. Używam czegoś takiego:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-30 14:30:32
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
Coś z Devise
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-19 00:25:43
Inna metoda, którą lubię używać
rand(2**256).to_s(36)[0..7]
Dodaj ljust, jeśli naprawdę masz paranoję co do prawidłowej długości strun:
rand(2**256).to_s(36).ljust(8,'a')[0..7]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-08 23:17:16
Myślę, że to miła równowaga zwięzłości, jasności i łatwości modyfikacji.
characters = ('a'..'z').to_a + ('A'..'Z').to_a
# Prior to 1.9, use .choice, not .sample
(0..8).map{characters.sample}.join
Łatwo modyfikować
Na przykład, w tym cyfry:
characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
Wielkie Litery szesnastkowe:
characters = ('A'..'F').to_a + (0..9).to_a
Dla naprawdę imponującej tablicy znaków:
characters = (32..126).to_a.pack('U*').chars.to_a
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-23 20:34:38
Dodaję tu moje grosze...
def random_string(length = 8)
rand(32**length).to_s(32)
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-16 02:22:00
Możesz użyć String#random
z aspektów rubinowego klejnotu facets
:
W zasadzie robi to:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 22:53:52
Moim ulubionym jest (:A..:Z).to_a.shuffle[0,8].join
. Zauważ, że shuffle wymaga Ruby > 1.9.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-28 18:18:17
To rozwiązanie wymaga zależności zewnętrznej, ale wydaje się ładniejsze niż inne.
- Install gem faker
Faker::Lorem.characters(10) # => "ang9cbhoa8"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 16:12:49
Podane:
chars = [*('a'..'z'),*('0'..'9')].flatten
Pojedyncze wyrażenie, może być przekazane jako argument, pozwala na duplikowanie znaków:
Array.new(len) { chars.sample }.join
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-31 09:56:55
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-26 18:03:50
Moje 2 grosze:
def token(length=16)
chars = [*('A'..'Z'), *('a'..'z'), *(0..9)]
(0..length).map {chars.sample}.join
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-03 15:49:14
Po prostu piszę mały klejnot random_token
aby wygenerować losowe tokeny dla większości przypadków użycia, enjoy ~
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-03 04:01:18
Dzięki tej metodzie możesz przejść w długości abitralnej. Jest ustawiony jako domyślny jako 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 00:53:41
Jak na razie najbardziej podoba mi się odpowiedź Radara. Podkręciłbym trochę tak:
CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
s=''
length.times{ s << CHARS[rand(CHARS.length)] }
s
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 02:35:00
Ostatnio robiłem coś takiego, aby wygenerować losowy ciąg 8 bajtów z 62 znaków. Znaki były 0-9, a-z,A-Z. miałem tablicę z nich, jak było zapętlanie 8 razy i wybierając losową wartość z tablicy. To było wewnątrz aplikacji rails.
str = ''
8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }
Ten kod był przed utworzeniem obiektu activerecord. Przed utworzeniem rekordu kod ten uruchamiał się i generował kod 'unikalny'. Wpisy w db zawsze były tworzone rzetelnie, ale kod (str w powyższej linii) był powielany zbyt często.
I created a script to run through 100000 iteracji tej powyżej linii z niewielkim opóźnieniem, więc zajęłoby to 3-4 godziny w nadziei, że zobaczę jakiś wzór powtarzania na godzinę, ale nic nie widziałem. Nie mam pojęcia, dlaczego tak się dzieje w mojej aplikacji rails.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-07 20:16:09