Obecnie generuję 8-znakowy pseudolosowy ciąg wielkich liter dla „A” .. „Z”:
value = ""; 8.times{value << (65 + rand(25)).chr}
ale nie wygląda na czysty i nie można go przekazać jako argumentu, ponieważ nie jest to pojedyncze stwierdzenie. Aby uzyskać ciąg „a” .. „z” plus „A” .. „Z”, zmieniłem go na:
value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr}
ale wygląda jak śmieci.
Czy ktoś ma lepszą metodę?
reset_user_password!(random_string)
gdziedef random_string; SecureRandom.urlsafe_base64(20) end
securerandom.urlsafe_base64
Odpowiedzi:
Zbyt dużo czasu spędzam na grze w golfa.
I ostatni, jeszcze bardziej zagmatwany, ale bardziej elastyczny i marnujący mniej cykli:
źródło
('a'..'z').to_a.shuffle[0,8].join
. Uwaga: potrzebujesz Ruby> = 1,9 doshuffle
.SecureRandom
jako jeden przykład w innych odpowiedziach.[*('a'..'z'),*('0'..'9')].shuffle[0,8].join
aby wygenerować losowy ciąg zawierający zarówno litery, jak i cyfry.rand
jest deterministyczny i przewidywalny. Nie używaj tego do generowania haseł!SecureRandom
Zamiast tego użyj jednego z rozwiązań.Dlaczego nie skorzystać z SecureRandom?
SecureRandom ma również metody:
patrz: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
źródło
require 'securerandom'
zdobyć tego schludnegoSecureRandom
pomocnika :)SecureRandom.random_number(36**12).to_s(36).rjust(12, "0")
wygeneruje ciąg z 0-9a-z (36 znaków), który ZAWSZE ma 12 znaków. Zmień 12 na dowolną długość. Niestety nie ma sposobu, aby po prostu użyć AZInteger#to_s
.+fGH1
adres URL, musisz go zakodować, tak jak%2BfGH1
Używam tego do generowania ciągów przyjaznych losowym adresom URL o gwarantowanej maksymalnej długości:
Generuje losowe ciągi małych liter az i 0-9. Nie jest bardzo konfigurowalny, ale jest krótki i czysty.
źródło
rand.to_s
; brzydkie, ale działa.length
długości, mniej więcej raz na ~ 40(36**(length-1) + rand(36**length)).to_s(36)
. 36 ** (długość-1) przeliczona na podstawę 36 wynosi 10 ** (długość-1), co jest najmniejszą wartością o żądanej długości cyfr.(36**(length-1) + rand(36**length - 36**(length-1))).to_s(36)
NameError: undefined local variable or method
length 'for main: Object`To rozwiązanie generuje ciąg łatwo czytelnych znaków dla kodów aktywacyjnych; Nie chciałem, żeby ludzie mylili 8 z B, 1 z I, 0 z O, L z 1 itd.
źródło
SecureRandom.random_number(charset.size)
zamiastrand(charset.size)
%w{ A C D E F G H J K L M N P Q R T W X Y Z 2 3 4 6 7 9 ! @ # $ % ^ & * +}
i%w{ A D E F G H J L N Q R T Y a d e f h n r y 2 3 4 7 ! @ # $ % ^ & * }
(pierwsza lista nie zawiera małych liter, ale jest dłuższa) Trochę interesujące, jak to wypracowane.Inni wspominali o czymś podobnym, ale używa to bezpiecznej funkcji adresu URL.
Wynik może zawierać AZ, az, 0-9, „-” i „_”. „=” Jest także używane, jeśli wypełnienie jest prawdziwe.
źródło
Od Ruby 2.5 jest to naprawdę łatwe dzięki
SecureRandom.alphanumeric
:Generuje losowe ciągi zawierające AZ, az i 0-9 i dlatego powinno mieć zastosowanie w większości przypadków użycia. I są generowane losowo bezpieczne, co również może być zaletą.
Jest to punkt odniesienia w porównaniu z rozwiązaniem mającym najwięcej pozytywnych opinii:
Tak więc
rand
rozwiązanie zajmuje tylko około 3/4 czasuSecureRandom
. Może to mieć znaczenie, jeśli wygenerujesz wiele ciągów, ale jeśli od czasu do czasu utworzysz jakiś losowy ciąg, zawsze będę korzystał z bezpieczniejszej implementacji, ponieważ łatwiej jest także wywoływać i bardziej jawnie.źródło
Wygeneruj losowy ciąg 8 liter (np. NVAYXHGR)
Wygeneruj losowy ciąg 8 znaków (np. 3PH4SWF2), z wyłączeniem 0/1 / I / O. Ruby 1.9
źródło
[*("A".."Z")]'
; ((nie pojedyncze kwity))stub
torspec
przekazać.Nie pamiętam, gdzie to znalazłem, ale wydaje mi się, że to najlepszy i najmniej wymagający proces:
źródło
0
I1
iO
iI
zostały celowo brakuje, ponieważ te znaki są niejednoznaczne. Jeśli ten rodzaj kodu jest używany do generowania zestawu znaków, które użytkownik musi skopiować, najlepiej jest wykluczyć znaki, które mogą być trudne do odróżnienia poza kontekstem.źródło
Random.new.bytes(9)
n=9 ; SecureRandom.urlsafe_base64(n)[0..n-1]
Jeśli chcesz ciąg o określonej długości, użyj:
Wygeneruje losowy ciąg długości
2n
zawierający0-9
ia-f
źródło
n
, w rzeczywistości generuje ciąg, który ma 4/3 długościn
..hex
jego 2n. Dokumentacja: SecureRandom.hex generuje losowy ciąg szesnastkowy. Argument n określa długość (w bajtach) losowej liczby do wygenerowania. Długość wynikowego ciągu szesnastkowego jest dwa razy większa od n .Array.new(n){[*"0".."9"].sample}.join
, gdzien=8
w twoim przypadku.Uogólnione:
Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
itp.Od: „ Wygeneruj pseudolosowy ciąg AZ, 0–9 ”.
źródło
źródło
Oto prosty, jednoliniowy kod losowego ciągu o długości 8:
Możesz go również użyć do losowego hasła o długości 8:
źródło
P(36, 8) / 36^8 = 0.4
możliwej przestrzeni znaków dla 8 znaków (~ 2x łatwiejsza brutalna siła) lubP(36, 25) / 36^25 = 0.00001
możliwej przestrzeni postaci dla 25 znaków (~ 100 000x łatwiejszej brutalnej siły).Ruby 1.9+:
źródło
map
Rozwiązanie jest naprawdę ładny!#sample
ile elementów chcesz. Np.ALPHABET.sample(10).join
... ruby-doc.org/core-2.4.0/Array.html#method-i-samplesample(10)
daje 10 unikalnych próbek. Ale chcesz pozwolić im się powtórzyć. Ale chciałbym użyćArray.new(10).map
do wykonaniaArray.new
i jego składnię bloków.Array.new(20) { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join
Bądź świadomy:
rand
jest przewidywalny dla atakującego i dlatego prawdopodobnie niepewny. Zdecydowanie powinieneś użyć SecureRandom, jeśli jest to do generowania haseł. Używam czegoś takiego:źródło
Oto jeden prosty kod losowego hasła o długości 8:
źródło
Kolejna metoda, której lubię używać:
Dodaj,
ljust
jeśli naprawdę jesteś paranoikiem w kwestii prawidłowej długości łańcucha:źródło
Coś z Devise
źródło
.tr('+/=lIO0', 'pqrsxyz')
?Myślę, że to niezła równowaga zwięzłości, jasności i łatwości modyfikacji.
Łatwo modyfikowany
Na przykład z cyframi:
Wielkie litery szesnastkowe:
Aby uzyskać naprawdę imponujący zestaw znaków:
źródło
Właśnie dodałem tutaj swoje centy ...
źródło
rand
Możesz użyć
String#random
z Facets of Ruby Gemfacets
.Zasadniczo robi to:
źródło
Moim ulubionym jest
(:A..:Z).to_a.shuffle[0,8].join
. Zauważ, że losowanie wymaga Ruby> 1.9.źródło
To rozwiązanie wymaga zewnętrznej zależności, ale wydaje się ładniejsze niż inne.
Faker::Lorem.characters(10) # => "ang9cbhoa8"
źródło
Dany:
Pojedyncze wyrażenie, które można przekazać jako argument, umożliwia duplikowanie znaków:
źródło
Myślę, że najbardziej podoba mi się odpowiedź Radar. Poprawiłbym trochę tak:
źródło
(CHARS*length).sample(length).join
?CHARS=['a','b']
twoja metoda wygeneruje"aa"
lub"bb"
tylko 33% czasu, ale"ab"
lub"ba"
67% czasu. Może to nie jest problem, ale warto o tym pamiętać!źródło
Moje 2 centy:
źródło
Właśnie piszę mały klejnot,
random_token
aby wygenerować losowe tokeny dla większości przypadków użycia, ciesz się ~https://github.com/sibevin/random_token
źródło
2 rozwiązania dla ciągu losowego składającego się z 3 zakresów:
Jedna postać z każdego zakresu.
A jeśli potrzebujesz co najmniej jednego znaku z każdego zakresu, na przykład utworzenia losowego hasła, które ma jedną wielką literę, jedną małą literę i jedną cyfrę, możesz zrobić coś takiego:
źródło
( ('a'..'z').to_a.sample(8) + ('A'..'Z').to_a.sample(8) + (0..9).to_a.sample(8) + [ "%", "!", "*" ].sample(8) ).shuffle.join #=> "Kc5zOGtM0*H796QgPp%!8u2Sxo1"
Ostatnio robiłem coś takiego, aby wygenerować 8-bajtowy ciąg losowy z 62 znaków. Znaki to 0-9, az, AZ. Miałem ich tablicę, ponieważ zapętlałem 8 razy i wybrałem losową wartość z tablicy. To było w aplikacji Rails.
Dziwne jest to, że mam dużą liczbę duplikatów. Teraz losowo to raczej nie powinno się zdarzyć. 62 ^ 8 jest ogromny, ale z około 1200 kodów w db miałem dużą liczbę duplikatów. Zauważyłem, że zdarzają się one na godzinnych granicach. Innymi słowy, mogę zobaczyć duplikat o 12:12:23 i 2:12:22 lub coś w tym rodzaju ... nie jestem pewien, czy czas jest problemem, czy nie.
Ten kod znajdował się przed utworzeniem obiektu ActiveRecord. Przed utworzeniem rekordu ten kod działałby i generował „unikalny” kod. Wpisy w DB zawsze były tworzone niezawodnie, ale kod (
str
w powyższym wierszu) był zbyt często kopiowany.Stworzyłem skrypt, który uruchamiałby 100 000 iteracji powyższej linii z niewielkim opóźnieniem, więc zajęłoby to 3-4 godziny w nadziei, że zobaczę jakiś wzór powtarzalny co godzinę, ale nic nie zobaczyłem. Nie mam pojęcia, dlaczego tak się dzieje w mojej aplikacji Rails.
źródło