Ich generiere gerade eine 8-stellige pseudozufällige Großbuchstabenfolge für "A" .. "Z":
value = ""; 8.times{value << (65 + Rand(25)).chr}
es sieht jedoch nicht sauber aus und kann nicht als Argument übergeben werden, da es keine einzige Anweisung ist. Um eine Zeichenfolge "a" .. "z" plus "A" .. "Z" zu erhalten, habe ich sie geändert:
value = ""; 8.times{value << ((Rand(2)==1?65:97) + Rand(25)).chr}
aber es sieht aus wie Müll.
Hat jemand eine bessere Methode?
(0...8).map { (65 + Rand(26)).chr }.join
Ich verbringe zu viel Zeit mit Golf.
(0...50).map { ('a'..'z').to_a[Rand(26)] }.join
Und eine letzte, die noch verwirrender ist, aber flexibler ist und weniger Zyklen verbraucht:
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[Rand(o.length)] }.join
Warum nicht SecureRandom verwenden?
require 'securerandom'
random_string = SecureRandom.hex
# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)
SecureRandom bietet auch Methoden für:
siehe: http://Ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
Ich verwende dies zum Generieren von URL-freundlichen Zeichenfolgen mit einer garantierten maximalen Länge:
Rand(36**length).to_s(36)
Es erzeugt zufällige Zeichenfolgen aus Kleinbuchstaben von a-z und 0-9. Es ist nicht sehr anpassbar, aber kurz und sauber.
Diese Lösung generiert eine Folge leicht lesbarer Zeichen für Aktivierungscodes. Ich wollte nicht, dass die Leute 8 mit B verwechseln, 1 mit I, 0 mit O, L mit 1 usw.
# 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
Andere haben etwas ähnliches erwähnt, aber dies verwendet die URL-sichere Funktion.
require 'securerandom'
p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
Das Ergebnis kann A-Z, a-z, 0-9, "-" und "_" enthalten. “=” Wird auch verwendet, wenn das Auffüllen wahr ist.
[*('A'..'Z')].sample(8).join
Eine zufällige Zeichenfolge mit 8 Buchstaben erstellen (z. B. NVAYXHGR)
([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(8).join
Generieren Sie eine zufällige 8-stellige Zeichenfolge (z. B. 3PH4SWF2), ausgenommen 0/1/I/O. Ruby 1,9
Seit Ruby 2.5 wirklich einfach mit SecureRandom.alphanumeric
:
len = 8
SecureRandom.alphanumeric(len)
=> "larHSsgL"
Erzeugt zufällige Zeichenfolgen mit A-Z, a-z und 0-9 und sollte daher in den meisten Anwendungsfällen anwendbar sein. Und sie werden zufällig sicher generiert, was ebenfalls von Vorteil sein kann.
Edit: Ein Benchmark zum Vergleich mit der Lösung mit den meisten 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)
Die Rand
-Lösung benötigt also nur etwa 3/4 der Zeit von SecureRandom
. Vielleicht ist es wichtig, wenn Sie wirklich sehr viele Zeichenfolgen generieren, aber wenn Sie nur gelegentlich zufällige Zeichenfolgen erstellen, gehe ich immer mit der sichereren Implementierung (da sie auch einfacher aufzurufen und expliziter ist).
Ich kann mich nicht erinnern, wo ich das gefunden habe, aber es scheint mir das beste und das am wenigsten intensive Verfahren zu sein:
def random_string(length=10)
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
password = ''
length.times { password << chars[Rand(chars.size)] }
password
end
require 'securerandom'
SecureRandom.urlsafe_base64(9)
Wenn Sie eine Zeichenfolge mit der angegebenen Länge wünschen, verwenden Sie:
require 'securerandom'
randomstring = SecureRandom.hex(n)
Es wird eine zufällige Zeichenfolge der Länge 2n
generiert, die 0-9
und a-f
enthält.
Array.new(n){[*"0".."9"].sample}.join
, Dabei ist n = 8 in Ihrem Fall.
Generalized: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
usw. - von hier antworten
require 'sha1'
srand
seed = "--#{Rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]
Hier ist ein einfacher Code für eine zufällige Zeichenfolge mit der Länge 8
random_string = ('0'..'z').to_a.shuffle.first(8).join
Sie können es auch für ein beliebiges Passwort mit der Länge 8 verwenden
random_password = ('0'..'z').to_a.shuffle.first(8).join
ich hoffe es wird helfen und erstaunlich.
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"
Beachten Sie: Rand
ist für einen Angreifer vorhersehbar und daher wahrscheinlich unsicher. Sie sollten SecureRandom auf jeden Fall verwenden, wenn dies zur Generierung von Passwörtern dient. Ich benutze so etwas:
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
Hier ist ein einfacher Code für ein beliebiges Passwort mit der Länge 8
Rand_password=('0'..'z').to_a.shuffle.first(8).join
Ich hoffe es wird helfen.
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
Etwas von Devise
Einfach meine Cents hier hinzufügen ...
def random_string(length = 8)
Rand(32**length).to_s(32)
end
sie können String#random
aus den Facetten von Ruby Gem facets
verwenden:
es tut im Grunde Folgendes:
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
Eine andere Methode, die ich gerne benutze
Rand(2**256).to_s(36)[0..7]
Fügen Sie ljust hinzu, wenn Sie wirklich paranoid bezüglich der korrekten Saitenlänge sind:
Rand(2**256).to_s(36).ljust(8,'a')[0..7]
Ich denke, dass dies eine schöne Balance zwischen Prägnanz, Klarheit und einfacher Modifikation ist.
characters = ('a'..'z').to_a + ('A'..'Z').to_a
# Prior to 1.9, use .choice, not .sample
(0..8).map{characters.sample}.join
Zum Beispiel, einschließlich Ziffern:
characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
Hexadezimal in Großbuchstaben:
characters = ('A'..'F').to_a + (0..9).to_a
Für eine wirklich beeindruckende Reihe von Charakteren:
characters = (32..126).to_a.pack('U*').chars.to_a
Mein Favorit ist (:A..:Z).to_a.shuffle[0,8].join
. Beachten Sie, dass Shuffle Ruby> 1.9 erfordert.
Diese Lösung benötigt externe Abhängigkeit, scheint aber hübscher als eine andere.
Faker::Lorem.characters(10) # => "ang9cbhoa8"
Gegeben:
chars = [*('a'..'z'),*('0'..'9')].flatten
Einzelner Ausdruck, kann als Argument übergeben werden, ermöglicht doppelte Zeichen:
Array.new(len) { chars.sample }.join
Meine 2 Cent:
def token(length=16)
chars = [*('A'..'Z'), *('a'..'z'), *(0..9)]
(0..length).map {chars.sample}.join
end
Ich schreibe einfach einen kleinen Edelstein random_token
, um zufällige Token für die meisten Anwendungsfälle zu generieren, ~
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
Ich habe in letzter Zeit so etwas getan, um eine zufällige 8-Byte-Zeichenfolge aus 62 Zeichen zu generieren. Die Zeichen waren 0-9, a-z, A-Z. Ich hatte ein Array von ihnen, als ich 8 Mal in einer Schleife war und einen zufälligen Wert aus dem Array auswählte. Dies war in einer Rails-App.
str = ''
8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[Rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }
Das Merkwürdige ist, dass ich eine gute Anzahl von Duplikaten bekam. Zufällig sollte das so ziemlich nie passieren. 62 ^ 8 ist riesig, aber von etwa 1200 Codes in der Datenbank hatte ich eine gute Anzahl von Duplikaten. Ich bemerkte, dass sie an stündlichen Grenzen voneinander passierten. Mit anderen Worten, ich könnte ein Duell um 12:12:23 und 2:12:22 oder so ähnlich sehen ... nicht sicher, ob es Zeit ist oder nicht.
Dieser Code befand sich im Vorher-Zustand eines Aktivierungsaufzeichnungsobjekts. Bevor der Datensatz erstellt wurde, würde dieser Code ausgeführt und der "eindeutige" Code generiert. Einträge in der DB wurden immer zuverlässig erzeugt, aber der Code (str in der obigen Zeile) wurde viel zu oft dupliziert.
Ich erstellte ein Skript, um 100000 Iterationen dieser oberen Zeile mit einer kleinen Verzögerung durchzugehen. Es würde 3-4 Stunden dauern, in der Hoffnung, stündlich ein Wiederholungsmuster zu sehen, aber nichts gesehen. Ich habe keine Ahnung, warum dies in meiner Rails-App passiert ist.
Wenn Sie sich unter UNIX befinden und Ruby 1.8 (kein SecureRandom) ohne Rails verwenden müssen, können Sie auch Folgendes verwenden:
random_string = `openssl Rand -base64 24`
Beachten Sie, dass dies zu einer neuen Shell führt. Dies ist sehr langsam und kann nur für Skripts empfohlen werden.
Ein weiterer Trick, der mit Ruby 1.8+ funktioniert und schnell geht, ist:
>> require "openssl"
>> OpenSSL::Random.random_bytes(20).unpack('H*').join
=> "2f3ff53dd712ba2303a573d9f9a8c1dbc1942d28"
Es ist eine zufällige Hex-Zeichenfolge. Auf ähnliche Weise sollten Sie Base64-Zeichenfolge ('M *') generieren können.
Ich mag die Antwort von Radar am besten, denke ich. Ich würde ein bisschen so tweak:
CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def Rand_string(length=8)
s=''
length.times{ s << CHARS[Rand(CHARS.length)] }
s
end
Mit dieser Methode können Sie eine beliebige Länge übergeben. Der Standardwert ist 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
Mein bester Schuss, 2 Lösungen für eine zufällige Saite bestehend aus 3 Bereichen
(('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a).sample(8).join
([*(48..57),*(65..90),*(97..122)]).sample(8).collect(&:chr)*""
probiere das aus
def Rand_name(len=9)
ary = [('0'..'9').to_a, ('a'..'z').to_a, ('A'..'Z').to_a]
name = ''
len.times do
name << ary.choice.choice
end
name
end
Ich liebe die Antworten des Threads, war wirklich sehr hilfreich!, Aber wenn ich sagen darf, befriedigt keiner von ihnen meine ayes, vielleicht ist die Rand () - Methode. Es scheint mir einfach nicht richtig zu sein, da wir die Array # Wahlmethode haben.
Hier ist eine andere Methode:
Benötigt require "securerandom"
def secure_random_string(length = 32, non_ambiguous = false)
characters = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
%w{I O l 0 1}.each{ |ambiguous_character|
characters.delete ambiguous_character
} if non_ambiguous
(0...length).map{
characters[ActiveSupport::SecureRandom.random_number(characters.size)]
}.join
end
10.times do
alphabet = ('a'..'z').to_a
string += alpha[Rand(alpha.length)]
end
Dies basiert auf ein paar anderen Antworten, erhöht jedoch die Komplexität:
def random_password
specials = ((32..47).to_a + (58..64).to_a + (91..96).to_a + (123..126).to_a).pack('U*').chars.to_a
numbers = (0..9).to_a
alpha = ('a'..'z').to_a + ('A'..'Z').to_a
%w{i I l L 1 O o 0}.each{ |ambiguous_character|
alpha.delete ambiguous_character
}
characters = (alpha + specials + numbers)
password = Random.new.Rand(8..18).times.map{characters.sample}
password << specials.sample unless password.join =~ Regexp.new(Regexp.escape(specials.join))
password << numbers.sample unless password.join =~ Regexp.new(Regexp.escape(numbers.join))
password.shuffle.join
end
Es stellt im Wesentlichen sicher, dass ein Kennwort zwischen 8 und 20 Zeichen lang ist und mindestens eine Zahl und ein Sonderzeichen enthält.
Für devise secure_validatable können Sie dies verwenden
(0 ... 8) .map {([65, 97] .beispiel + Rand (26)). Chr} .Push (Rand (99)). Join
Hier ist eine Verbesserung der Antwort von @Travis R:
def random_string(length=5)
chars = 'abdefghjkmnpqrstuvwxyzABDEFGHJKLMNPQRSTUVWXYZ'
numbers = '0123456789'
random_s = ''
(length/2).times { random_s << numbers[Rand(numbers.size)] }
(length - random_s.length).times { random_s << chars[Rand(chars.size)] }
random_s.split('').shuffle.join
end
Bei @Travis R waren die Antwortzeichen und Zahlen zusammen, sodass random_string
manchmal nur Zahlen oder nur Zeichen zurückgeben konnte. Bei dieser Verbesserung besteht mindestens die Hälfte von random_string
aus Zeichen und der Rest sind Zahlen. Nur für den Fall, dass Sie eine zufällige Zeichenfolge mit Zahlen und Zeichen benötigen
Um Ihre erste Aussage zu machen:
(0...8).collect { |n| value << (65 + Rand(25)).chr }.join()
Der einfachste Weg ist die Verwendung des Gems string_pattern https://github.com/MarioRuiz/string_pattern
Zum Beispiel um 36 zufällige Buchstaben zu generieren:
require 'string_pattern'
puts '36:L'.gen
Sie können auch reguläre Ausdrücke verwenden
require 'string_pattern'
puts /[a-zA-Z]{36}/.gen
Erstellen Sie einen leeren String oder einen Pre-Fix, wenn dies erforderlich ist:
myStr = "OID-"
Verwenden Sie diesen Code, um die Zeichenfolge mit Zufallszahlen zu füllen:
begin; n = ((Rand * 43) + 47).ceil; myStr << n.chr if !(58..64).include?(n); end while(myStr.length < 12)
Anmerkungen:
(Rand * 43) + 47).ceil
Es werden Zufallszahlen von 48-91 (0,1,2..Y, Z) generiert.
!(58..64).include?(n)
Es wird verwendet, um Sonderzeichen zu überspringen (da ich nicht daran interessiert bin, sie einzufügen)
while(myStr.length < 12)
Es werden insgesamt 12 Zeichen einschließlich des Präfixes generiert.
Beispielausgabe:
"OID-XZ2J32XM"
a='';8.times{a<<[*'a'..'z'].sample};p a
oder
8.times.collect{[*'a'..'z'].sample}.join
Wir haben dies in unserem Code verwendet:
class String
def self.random(length=10)
('a'..'z').sort_by {Rand}[0,length].join
end
end
Die maximal unterstützte Länge beträgt 25 (wir verwenden sie nur mit der Standardeinstellung, waren also kein Problem).
Jemand erwähnte, dass 'a' .. 'z' suboptimal ist, wenn Sie völlig vermeiden wollen, beleidigende Wörter zu erzeugen. Eine der Ideen, die wir hatten, bestand darin, Vokale zu entfernen, aber am Ende bleibt WTFBBQ usw.
`pwgen 8 1`.chomp
Hier ist eine Lösung, die flexibel ist und Dups ermöglicht:
class String
# generate a random string of length n using current string as the source of characters
def random(n)
return "" if n <= 0
(chars * (n / length + 1)).shuffle[0..n-1].join
end
end
Beispiel:
"ATCG".random(8) => "CGTGAAGA"
Sie können auch zulassen, dass ein bestimmtes Zeichen häufiger erscheint:
"AAAAATCG".random(10) => "CTGAAAAAGC"
Erläuterung: Die obige Methode nimmt die Zeichen einer gegebenen Zeichenfolge und generiert ein ausreichend großes Array. Es mischt es dann, nimmt die ersten n Elemente und fügt sie dann zusammen.
Array.new(8).inject(""){|r|r<<('0'..'z').to_a.shuffle[0]} # 57
(1..8).inject(""){|r|r<<('0'..'z').to_a.shuffle[0]} # 51
e="";8.times{e<<('0'..'z').to_a.shuffle[0]};e # 45
(1..8).map{('0'..'z').to_a.shuffle[0]}.join # 43
(1..8).map{Rand(49..122).chr}.join # 34
Verwenden Sie 'SafeRandom' Gem GithubLink
Es bietet die einfachste Möglichkeit, Zufallswerte für mit Rails2, Rails 3, Rails 4 und Rails 5 kompatible Werte zu generieren.