Frage

Ich bin derzeit Erzeugung eines 8-stelligen Pseudozufallsgroß Zeichenfolge für "A" .. "Z":

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

, aber es sieht nicht sauber, und es kann nicht als Argument übergeben werden, da es keine einzige Aussage. Um eine mixed-case Zeichenfolge "a" .. "z" plus "A" .. "Z" zu bekommen, habe ich es zu:

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

, aber es sieht aus wie Müll.

Hat jemand eine bessere Methode hat?

War es hilfreich?

Lösung

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

Ich verbringe zu viel Zeit Golfen.

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

Und ein letzter, die noch verwirrender ist, aber flexibler und Abfälle weniger Zyklen:

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

Andere Tipps

Warum nicht Secure benutzen?

require 'securerandom'
random_string = SecureRandom.hex

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

Secure hat auch Methoden für:

  • base64
  • random_bytes
  • random_number

siehe: http: // ruby-doc. org / stdlib-1.9.2 / libdoc / Secure / rdoc / SecureRandom.html

Ich benutze diese zur Erzeugung von Zufalls URL freundliche Strings mit einer garantierten maximalen Länge:

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

Es erzeugt zufällige Zeichenkette von Klein a-z und 0-9. Es ist nicht sehr individuell, aber es ist kurz und sauber.

Diese Lösung erzeugt eine Reihe von leicht lesbaren Zeichen für Aktivierungscodes; Ich wollte nicht, Menschen verwirrend 8 mit B, 1 mit I, 0 mit O, L mit 1, etc.

# 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 diese 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 enthält ein-Z, a-z, 0-9, „-“ und „_“. „=“ Wird auch verwendet, wenn padding wahr ist.

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

Generieren eines Zufalls 8 Buchstabenfolge (z NVAYXHGR)

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

Generieren eines Zufalls 8 Zeichenkette (beispiels 3PH4SWF2) schließt 0/1 / I / O. Ruby 1.9

Da Rubin 2.5 einfach mit SecureRandom.alphanumeric:

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

Erzeugt zufällige Zeichenkette A-Z enthalten, a-z und 0-9 und daher anwendbar sein sollten in den meisten Anwendungsfällen. Und sie werden zufällig sicher erzeugt, was ein Vorteil sein könnte, auch.


Edit: Ein Benchmark es mit der Lösung zu vergleichen, die die meisten upvotes mit:

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)

So ist die rand Lösung dauert nur etwa 3/4 der Zeit von SecureRandom. Rolle könnte, wenn Sie wirklich eine Menge Saiten erzeugen, aber wenn Sie nur eine zufällige Zeichenfolge von Zeit zu Zeit erstellen würde ich immer mit der sichereren Implementierung gehen (da es auch leichter zu nennen und expliziter ist).

Ich kann mich nicht erinnern, wo ich das gefunden, aber es scheint, wie das am besten und den am wenigsten Prozess intensiv zu mir:

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 einen String der angegebenen Länge möchten, verwenden Sie:

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

Es wird eine zufällige Zeichenfolge der Länge 2n enthält 0-9 und a-f

erzeugen

Array.new(n){[*"0".."9"].sample}.join, wobei n = 8 in Ihrem Fall.

Generalized: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join etc. - von diese beantworten

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

Hier ist eine Zeile einfacher Code für zufälligen Zeichenfolge mit einer Länge von 8

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

Sie können es auch für zufällige Passwörter verwenden, die Länge 8

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"

Hier ist ein einfacher Code für zufällige Passwörter mit einer Länge von 8

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

Hoffe, es wird helfen.

Bitte beachten Sie: rand für einen Angreifer vorhersehbar ist und daher wahrscheinlich unsicher. Sie sollten auf jeden Fall Secure verwenden, wenn dies zur Erzeugung von Passwörtern ist. Ich benutze so etwas wie folgt aus:

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

Eine andere Methode Ich mag verwenden

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

In ljust wenn Sie wirklich paranoid über die korrekte Stringlänge sind:

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

Etwas von Devise

Ich denke, das ist eine gute Balance von Prägnanz, Klarheit und Einfachheit der Änderung.

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

leicht modifiziert

Zum Beispiel, einschließlich der Ziffern:

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

Versalien- hexadezimal:

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

Für eine wirklich beeindruckende Reihe von Zeichen:

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

Nur das Hinzufügen meines Cent hier ...

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

Sie können String#random von den Facetten von Ruby Gem facets verwenden:

https://github.com/ rubyworks / Facetten / Blob / 126a619fd766bc45588cac18d09c4f1927538e33 / lib / core / Facetten / string / random.rb

es im Grunde tut dies:

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

Mein Favorit ist (:A..:Z).to_a.shuffle[0,8].join. Beachten Sie, dass shuffle setzt Rubin> 1.9.

Diese Lösung benötigt externe Abhängigkeit, scheint aber schöner als andere.

  1. Installieren gem faker
  2. Faker::Lorem.characters(10) # => "ang9cbhoa8"

Gegeben:

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

Single Ausdruck kann als Argument übergeben wird, läßt doppelte Zeichen:

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

Ich war so etwas wie dies zu tun vor kurzem eine 8-Byte-zufällige Zeichenfolge aus 62 Zeichen zu erzeugen. Die Zeichen waren 0-9, a-z, A-Z. Ich hatte von ihnen wurde ein Array als 8mal Looping und einen Zufallswert aus dem Array Kommissionierung. Dies war in einer Rails-Anwendung.

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

Die seltsame Sache ist, dass ich eine gute Anzahl von Duplikaten bekam. Jetzt zufällig sollte dies so ziemlich nie passieren. 62 ^ 8 ist riesig, aber aus 1200 oder so Codes in der db hatte ich eine gute Anzahl von Duplikaten. Ich bemerkte sie auf Stunde Grenzen voneinander geschieht. Mit anderen Worten, ich könnte einen Zweier bei 12.12.23 und 02.12.22 oder so ähnlich sieht ... nicht sicher, ob die Zeit das Problem ist oder nicht.

Dieser Code wurde in dem vor einem Activerecord-Objekt erstellen. Vor der Aufzeichnung dieser Code erstellt wurde, würde die ‚einmalige‘ Code auszuführen und generieren. Einträge in den db wurden immer zuverlässig hergestellt, aber der Code (str in der oberen Zeile) wurde viel zu oft dupliziert werden.

habe ich ein Skript über 100.000 Iterationen dieser über die Linie mit kleiner Verzögerung laufen, so dass es 3-4 Stunden eine Art Wiederholungsmuster auf stündliche Basis der Hoffnung nehmen würde, um zu sehen, sah aber nichts. Ich habe keine Ahnung, warum dies in meiner Rails-Anwendung geschieht.

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

Meine 2 Cent:

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

Ich schreibe gerade ein kleines Juwel random_token zufällige Token für die meisten Anwendungsfälle zu erzeugen, genießen ~

https://github.com/sibevin/random_token

Mit dieser Methode können Sie in beliebiger Länge passieren. Es ist festgelegt als Standard als 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

Ich mag Radar Antwort am besten, so weit, denke ich. Ich würde zwicken ein wenig wie folgt aus:

CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
  s=''
  length.times{ s << CHARS[rand(CHARS.length)] }
  s
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top