So generieren Sie eine zufällige Zeichenfolge in Ruby

747

Ich generiere derzeit eine 8-stellige pseudozufällige Großbuchstabenzeichenfolge für "A" .. "Z":

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

aber es sieht nicht sauber aus und kann nicht als Argument übergeben werden, da es keine einzelne Aussage ist. Um eine Zeichenfolge mit gemischten Groß- und Kleinschreibung "a" .. "z" plus "A" .. "Z" zu erhalten, habe ich sie geändert in:

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

aber es sieht aus wie Müll.

Hat jemand eine bessere Methode?

Jeff
quelle
Ich verstehe nicht, warum es Sie interessiert, dass "da es keine einzelne Aussage ist, kann sie nicht als Argument übergeben werden". Warum nicht einfach eine Dienstprogramm- oder Hilfsmethode erstellen?
David J.
1
Angenommen, es gibt eine Methode zum Zurücksetzen des Kennworts eines Benutzers und es gibt ein Argument für das neue Kennwort. Ich möchte eine zufällige Zeichenfolge übergeben, im obigen Code benötige ich eine tmp-Variable, während ich in den folgenden Beispielen für einzelne Anweisungen das Ganze als Einzeiler ausführen kann. Sicher, eine Utility-Methode könnte auf lange Sicht nützlich sein, besonders wenn ich hier und da etwas Ähnliches brauche, aber manchmal möchte man sie nur einmal an Ort und Stelle haben.
Jeff
Nein, Sie müssen keine temporäre Variable verwenden. Versuchen Sie dies: reset_user_password!(random_string)wodef random_string; SecureRandom.urlsafe_base64(20) end
David J.
8 Buchstaben ist ein beschämend schwaches Passwort. Mit der md5sum könnte ein moderner PC das Passwort in 30 Sekunden wiederherstellen . Wie wäre es mit etwas längeremsecurerandom.urlsafe_base64
Colonel Panic
1
Warum hat das so viele Antworten? Nicht, dass es keine nützliche Frage wäre, aber ich bin gespannt, wie sie Aufmerksamkeit erregt hat.
Lou

Antworten:

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

Ich verbringe zu viel Zeit mit Golfen.

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

Und eine letzte, die noch verwirrender, aber flexibler ist und weniger Zyklen verschwendet:

o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join
Kent Fredric
quelle
205
34 Zeichen und blitzschnell : ('a'..'z').to_a.shuffle[0,8].join. Beachten Sie, dass Sie Ruby> = 1,9 bis benötigen shuffle.
fny
20
Die Nutzung vorhandener Bibliotheken ist vorzuziehen, es sei denn, Sie haben einen Treiber, mit dem Sie Ihre eigenen rollen können. Siehe SecureRandomals ein Beispiel in den anderen Antworten.
David J.
28
@faraz Ihre Methode ist funktional nicht die gleiche, es ist nicht zufällig mit Ersatz.
michaeltwofish
35
[*('a'..'z'),*('0'..'9')].shuffle[0,8].joinum eine zufällige Zeichenfolge mit Buchstaben und Zahlen zu generieren.
Robin
31
randist deterministisch und vorhersehbar. Verwenden Sie dies nicht zum Generieren von Passwörtern! Verwenden Sie SecureRandomstattdessen eine der Lösungen.
Bleistift
800

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:

  • base64
  • random_bytes
  • Zufallszahl

Siehe: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html

christopherstyles
quelle
11
base64 würde, aber nicht hex wie in seinem Beispiel
Jeff Dickey
67
Übrigens, es ist Teil der stdlib in 1.9 und den neuesten 1.8-Versionen, also kann man nur require 'securerandom'diesen netten SecureRandomHelfer bekommen :)
J -_- L
21
BTW SecureRandom wurde in Version 3.2 aus ActiveSupport entfernt. Aus dem Änderungsprotokoll: "ActiveSupport :: SecureRandom wurde zugunsten von SecureRandom aus der Standardbibliothek entfernt".
Marc
15
SecureRandom.random_number(36**12).to_s(36).rjust(12, "0")generiert eine Zeichenfolge mit 0-9a-z (36 Zeichen), die IMMER 12 Zeichen lang ist. Ändern Sie 12 auf die gewünschte Länge. Leider keine Möglichkeit, AZ nur mit zu bekommen Integer#to_s.
Gerry Shaw
1
@ stringo0 das ist falsch. Wenn Sie +fGH1eine URL passieren möchten, müssen Sie sie nur wie einen Wert, der eine URL %2BfGH1
durchläuft
247

Ich verwende dies, um zufällige URL-freundliche Zeichenfolgen mit einer garantierten maximalen Länge zu generieren:

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

Es werden zufällige Zeichenfolgen mit Kleinbuchstaben az und 0-9 generiert. Es ist nicht sehr anpassbar, aber es ist kurz und sauber.

Christoffer Möller
quelle
4
+1 für die kürzeste Version (die keine externen Binärdateien aufruft ^^). Wenn die zufällige Zeichenfolge nicht öffentlich zugänglich ist, verwende ich sie manchmal sogar nur rand.to_s. hässlich, funktioniert aber.
Jo Liss
12
Dies ist eine großartige Lösung (und auch schnell), aber es wird gelegentlich eine Zeichenfolge unter length Länge erzeugt, ungefähr einmal in ~ 40
Brian E
7
@Brian E Dies würde die gewünschten Ziffern garantieren : (36**(length-1) + rand(36**length)).to_s(36). 36 ** (Länge 1), konvertiert in Basis 36, ist 10 ** (Länge 1). Dies ist der kleinste Wert mit der gewünschten Ziffernlänge.
Eric Hu
11
Hier ist die Version, die immer Token der gewünschten Länge produziert:(36**(length-1) + rand(36**length - 36**(length-1))).to_s(36)
Adrien Jarthon
3
Dies spuckt einen Fehler für mich in Rails 4 und Ruby 2.1.1 aus: NameError: undefined local variable or method Länge 'für main: Object`
kakubei
175

Diese Lösung generiert eine Zeichenfolge leicht lesbarer Zeichen für Aktivierungscodes. Ich wollte nicht, dass Leute 8 mit B, 1 mit I, 0 mit O, L mit 1 usw. verwechseln.

# 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
ImNotQuiteJack
quelle
3
Ist 'U' mehrdeutig oder ist das ein Tippfehler?
GTD
10
@gtd - Ja. U und V sind Ambigvovs.
Colin
1
@ Colin V ist da drin.
GTD
8
Um sicher zu gehen, möchten Sie auch SecureRandom.random_number(charset.size)anstelle vonrand(charset.size)
gtd
1
Ich habe nur versucht, dies zu verbessern, indem ich Kleinbuchstaben und / oder einige Sonderzeichen (Umschalt + Nummer) hinzugefügt habe, und habe die folgenden Listen erhalten: %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 ! @ # $ % ^ & * +}und %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 ! @ # $ % ^ & * }(erste Liste enthält keine Kleinbuchstaben, aber es ist länger) Ein bisschen interessant, wie das ist hat geklappt.
dkniffin
130

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 AZ, az, 0-9, "-" und "_" enthalten. "=" Wird auch verwendet, wenn die Auffüllung wahr ist.

Travis R.
quelle
Genau das habe ich gesucht. Vielen Dank!
Dan Williams
69

Seit Ruby 2.5 ist es ganz einfach mit SecureRandom.alphanumeric:

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

Es generiert zufällige Zeichenfolgen, die AZ, az und 0-9 enthalten, und sollte daher in den meisten Anwendungsfällen anwendbar sein. Und sie werden zufällig sicher generiert, was ebenfalls von Vorteil sein kann.


Dies ist ein Benchmark, um ihn mit der Lösung mit den meisten positiven Stimmen zu vergleichen:

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 randLösung dauert also nur etwa 3/4 der Zeit von SecureRandom. Das mag wichtig sein, wenn Sie viele Zeichenfolgen generieren, aber wenn Sie von Zeit zu Zeit nur eine zufällige Zeichenfolge erstellen, würde ich immer die sicherere Implementierung wählen, da sie auch einfacher aufzurufen und expliziter ist.

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

Generieren Sie eine zufällige Zeichenfolge mit 8 Buchstaben (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) ohne 0/1 / I / O. Ruby 1.9

Tom Carr
quelle
4
Das einzige Problem ist, dass jedes Zeichen im Ergebnis eindeutig ist. Begrenzt die möglichen Werte.
tybro0103
1
Wenn diese Funktionsanforderung ausgeführt wird, erhält Ruby 1.9.x möglicherweise #sample für die ersatzlose Stichprobe und #choice für die Stichprobe mit Ersetzung.
David J.
Dies ist ein Fehler, ich denke du brauchst ... [*("A".."Z")]'; ((nicht einzelne Qoutes))
Jayunit100
können Sie mir sagen , wie ich kann stubfür diese rspeczu übergeben.
Sinscary
31

Ich kann mich nicht erinnern, wo ich das gefunden habe, aber es scheint mir der beste und der am wenigsten prozessintensive zu sein:

def random_string(length=10)
  chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
  password = ''
  length.times { password << chars[rand(chars.size)] }
  password
end
Travis R.
quelle
7
Vielleicht haben Sie es hier gefunden? travisonrails.com/2007/06/07/generate-random-text-with-ruby
Deadwards
Fehlt hier nicht eine 0 und 1?
Sunnyrjuneja
Sieht so aus, als hätte ich es gefunden.
Travis Reeder
Und ja, es sieht so aus, als ob 0 und 1 fehlen.
Travis Reeder
4
Das 0und 1und Ound Ifehlten absichtlich, weil diese Zeichen nicht eindeutig sind. Wenn diese Art von Code verwendet wird, um eine Reihe von Zeichen zu generieren, die ein Benutzer kopieren muss, ist es am besten, Zeichen auszuschließen, die möglicherweise nur schwer außerhalb des Kontexts zu unterscheiden sind.
Andrew
28
require 'securerandom'
SecureRandom.urlsafe_base64(9)
LENZCOM
quelle
SecureRandom ist eine ausgezeichnete Bibliothek. Ich wusste nicht, dass es da war. Vielen Dank.
Dogweather
alte Schule (und hässlichere) Alternative:Random.new.bytes(9)
verspätet
4
Übrigens gibt urlsafe_base64 eine Zeichenfolge zurück, die ungefähr 4/3 der angegebenen Länge entspricht. Um lange einen String genau n Zeichen, versuchenn=9 ; SecureRandom.urlsafe_base64(n)[0..n-1]
tardate
25

Wenn Sie eine Zeichenfolge mit der angegebenen Länge möchten, verwenden Sie:

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

Es wird eine zufällige Zeichenfolge der Länge erzeugen 2nenthält 0-9unda-f

Srikanta Mahapatro
quelle
Es wird keine Zeichenfolge mit einer Länge ngeneriert, sondern eine Zeichenfolge mit einer Länge von 4/3 n.
Omar Ali
@OmarAli du liegst falsch. Gemäß Ruby-Dokumentation für den Fall, dass .hexes 2n ist. Dokumentation: SecureRandom.hex generiert eine zufällige hexadezimale Zeichenfolge. Das Argument n gibt die Länge der zu generierenden Zufallszahl in Bytes an. Die Länge der resultierenden hexadezimalen Zeichenfolge beträgt das Doppelte von n .
Rihards
11
require 'sha1'
srand
seed = "--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]
Coren
quelle
Interessant, aber viel rechenintensiver
Jeff
Auch keine Kapazität für begrenzten Zeichenumfang.
Kent Fredric
3
Beachten Sie, dass ein Hex-Digest nur 0-9 und af-Zeichen zurückgibt.
Webmat
11

Hier ist ein einzeiliger einfacher Code für zufällige Zeichenfolgen mit der Länge 8:

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

Sie können es auch für ein zufälliges Passwort mit der Länge 8 verwenden:

random_password = ('0'..'z').to_a.shuffle.first(8).join
Awais
quelle
2
Sie sollten dies nicht verwenden, um sich ein Passwort zu generieren, da diese Methode niemals ein Zeichen wiederholt. Daher verwenden Sie nur P(36, 8) / 36^8 = 0.4den möglichen Zeichenraum für 8 Zeichen (~ 2x leichter zu erzwingen) oder P(36, 25) / 36^25 = 0.00001den möglichen Zeichenraum für 25 Zeichen (~ 100.000x leichter zu erzwingen).
Gletscher
10

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"
Ragmaanir
quelle
1
Die mapLösung ist wirklich schön!
Mischa Moroshko
Sie können fragen, #samplewie viele Elemente Sie möchten. ZB ALPHABET.sample(10).join... ruby-doc.org/core-2.4.0/Array.html#method-i-sample
odlp
Das ist eigentlich falsch. sample(10)gibt Ihnen 10 einzigartige Proben. Aber Sie möchten, dass sie sich wiederholen. Aber ich würde Array.new(10).mapfür die Leistung verwenden
Saša Zejnilović
Ich wollte alphanumerisch mit Klein- und Großbuchstaben. Ich habe auch auf die Verwendung Array.newund deren Blocksyntax umgestellt . Array.new(20) { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join
Taylorthurlow
8

Seien Sie sich bewusst: randist für einen Angreifer vorhersehbar und daher wahrscheinlich unsicher. Sie sollten SecureRandom auf jeden Fall verwenden, wenn dies zum Generieren von Kennwö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
Bleistift
quelle
Dies ist wahrscheinlich die "sicherste" Lösung. SecureRandom versucht, zugrunde liegende Sicherheits-APIs zu verwenden, die vom Betriebssystem bereitgestellt werden. Wenn Sie OpenSSL haben, wird dies verwendet. Wenn Sie unter Windows arbeiten, ist dies die beste Option. Diese Lösung gefällt mir besonders, weil Sie damit eine Reihe von Zeichen für die Verwendung angeben können. Es funktioniert jedoch nicht, wenn Ihr Zeichensatz länger als der Maximalwert eines Bytes ist: 255. Ich empfehle, den Quellcode für SecureRandom im Dokument anzuzeigen
Breedly
8

Hier ist ein einfacher Code für ein zufälliges Passwort mit der Länge 8:

rand_password=('0'..'z').to_a.shuffle.first(8).join
Thaha kp
quelle
7

Eine andere Methode, die ich gerne benutze:

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

Fügen ljustSie hinzu, wenn Sie in Bezug auf die richtige Zeichenfolgenlänge wirklich paranoid sind:

 rand(2**256).to_s(36).ljust(8,'a')[0..7]
163365
quelle
Noch besser ist es, den niedrigstwertigen Teil der Zufallszahl mit der rechten Seite der Zeichenfolge zu erfassen: rand (2 ** 64) .to_s (36) [- 10,10]
Jeff
6
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')

Etwas von Devise

Teej
quelle
Warum werden Zeichenfolgen durch ersetzt .tr('+/=lIO0', 'pqrsxyz')?
Miguelcobain
Die Sonderzeichen, weil sie nicht URL-sicher sind. Und l / I oder O / 0, weil sie sehr leicht zu verwechseln sind, wenn Sie die Technik verwenden, um lesbare Benutzerkennwörter zu generieren.
ToniTornado
Diese Funktion ist ein wenig voreingenommen gegenüber bestimmten Zeichen. Auch für andere Längen (z. B. 16) ist das letzte Zeichen nicht zufällig. Hier ist ein Weg, dies zu vermeiden. SecureRandom.base64 (64) .tr ('+ / = lIO01', '') [0,16]
Shai Coleman
5

Ich denke, dies ist eine gute Balance zwischen Prägnanz, Klarheit und einfacher Modifikation.

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

Leicht zu modifizieren

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
Nathan Long
quelle
1
Ich würde dies empfehlen, um nur Großbuchstaben + Zahlen zu verwenden und auch die "verwirrenden" Zeichen zu entfernen. charset = (1..9) .to_a.concat (('A' .. 'Z'). to_a) .reject {| a | [0, 1, 'O', 'I'] umfasst (a)} (0 ... Größe) .map {charset [rand (charset.size)]} .join.?
Glanz
5

Ich füge hier nur meine Cent hinzu ...

def random_string(length = 8)
  rand(32**length).to_s(32)
end
Pduersteler
quelle
3
NB: Dies gibt nicht immer genau einen String + Länge + Länge zurück - er kann kürzer sein. Es hängt von der Zahl der zurück durchrand
tardate
5

Sie können String#randomaus den Facetten von Ruby Gem verwenden facets.

Es macht im Grunde das:

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
Tilo
quelle
4

Mein Favorit ist (:A..:Z).to_a.shuffle[0,8].join. Beachten Sie, dass für das Mischen Ruby> 1.9 erforderlich ist.

Josh
quelle
4

Diese Lösung benötigt externe Abhängigkeit, scheint aber hübscher als eine andere.

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

Gegeben:

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

Ein einzelner Ausdruck, der als Argument übergeben werden kann, ermöglicht doppelte Zeichen:

Array.new(len) { chars.sample }.join
Tim James
quelle
3

Die Antwort von Radar gefällt mir bisher am besten, denke ich. Ich würde ein bisschen so optimieren:

CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
  s=''
  length.times{ s << CHARS[rand(CHARS.length)] }
  s
end
Webmat
quelle
Warum nicht verwenden (CHARS*length).sample(length).join?
Niels
@niels Dieser Vorschlag würde eine gewichtete Zeichenfolge zugunsten nicht wiederholter Zeichen erzeugen . Zum Beispiel, wenn CHARS=['a','b']dann Ihre Methode "aa"oder "bb"nur 33% der Zeit, aber "ab"oder "ba"67% der Zeit generieren würde . Vielleicht ist das kein Problem, aber es lohnt sich, daran zu denken!
Tom Lord
Guter Punkt, @TomLord, ich glaube, ich habe das nicht wirklich bemerkt, als ich diesen Vorschlag gepostet habe (obwohl ich zugeben muss, dass ich mich überhaupt nicht daran erinnere, das gepostet zu haben: D)
niels
3
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
eric
quelle
3

Meine 2 Cent:

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

Ich schreibe nur einen kleinen Edelstein random_token, um zufällige Token für den meisten Anwendungsfall zu generieren. Viel Spaß ~

https://github.com/sibevin/random_token

Sibevin Wang
quelle
Tolles Juwel. Vielen Dank :)
Mirko Akov
3

2 Lösungen für eine zufällige Zeichenfolge 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)*""

Ein Zeichen aus jedem Bereich.

Und wenn Sie mindestens ein Zeichen aus jedem Bereich benötigen, z. B. ein zufälliges Passwort mit einem Großbuchstaben, einem Kleinbuchstaben und einer Ziffer erstellen, können Sie Folgendes tun:

( ('a'..'z').to_a.sample(8) + ('A'..'Z').to_a.sample(8) + (0..9).to_a.sample(8) ).shuffle.join 
#=> "Kc5zOGtM0H796QgPp8u2Sxo1"
Peter
quelle
Und wenn Sie eine bestimmte Anzahl von jedem Bereich erzwingen möchten, können Sie so etwas tun:( ('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"
Joshua Pinter
3

Ich habe kürzlich so etwas gemacht, um aus 62 Zeichen eine 8-Byte-Zufallszeichenfolge zu generieren. Die Zeichen waren 0-9, az, AZ. Ich hatte ein Array von ihnen, wie es 8-mal wiederholt wurde 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 Seltsame ist, dass ich eine gute Anzahl von Duplikaten habe. Zufällig sollte dies so gut wie nie passieren. 62 ^ 8 ist riesig, aber von ungefähr 1200 Codes in der Datenbank hatte ich eine gute Anzahl von Duplikaten. Ich bemerkte, dass sie an Stundengrenzen voneinander passierten. Mit anderen Worten, ich könnte ein Duplikat um 12:12:23 und 2:12:22 oder so etwas sehen ... nicht sicher, ob die Zeit das Problem ist oder nicht.

Dieser Code wurde vor dem Erstellen eines ActiveRecord-Objekts erstellt. Bevor der Datensatz erstellt wurde, wurde dieser Code ausgeführt und der "eindeutige" Code generiert. Einträge in der DB wurden immer zuverlässig erstellt, aber der Code ( strin der obigen Zeile) wurde viel zu oft dupliziert.

Ich habe ein Skript erstellt, um 100000 Iterationen dieser obigen Zeile mit geringer Verzögerung zu durchlaufen, sodass es 3-4 Stunden dauern würde, in der Hoffnung, stündlich ein Wiederholungsmuster zu sehen, aber nichts zu sehen. Ich habe keine Ahnung, warum dies in meiner Rails-App passiert ist.

erik
quelle