module Random::Formatter
Zufallszahlformatierer.
Formatiert generierte Zufallszahlen auf vielfältige Weise. Wenn 'random/formatter' angefordert wird, werden mehrere Methoden zum leeren Kernmodul Random::Formatter hinzugefügt, wodurch sie als Instanz- und Modulmethoden von Random verfügbar werden.
Die Standardbibliothek SecureRandom wird ebenfalls mit dem Modul erweitert, und die unten beschriebenen Methoden sind darin als Modulmethoden verfügbar.
Beispiele
Generiere zufällige hexadezimale Zeichenfolgen
require 'random/formatter' prng = Random.new prng.hex(10) #=> "52750b30ffbc7de3b362" prng.hex(10) #=> "92b15d6c8dc4beb5f559" prng.hex(13) #=> "39b290146bea6ce975c37cfc23" # or just Random.hex #=> "1aed0c631e41be7f77365415541052ee"
Generiere zufällige Base64-Zeichenfolgen
prng.base64(10) #=> "EcmTPZwWRAozdA==" prng.base64(10) #=> "KO1nIU+p9DKxGg==" prng.base64(12) #=> "7kJSM/MzBJI+75j8" Random.base64(4) #=> "bsQ3fQ=="
Generiere zufällige Binärzeichenfolgen
prng.random_bytes(10) #=> "\016\t{\370g\310pbr\301" prng.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337" Random.random_bytes(6) #=> "\xA1\xE6Lr\xC43"
Generiere alphanumerische Zeichenfolgen
prng.alphanumeric(10) #=> "S8baxMJnPl" prng.alphanumeric(10) #=> "aOxAg8BAJe" Random.alphanumeric #=> "TmP9OsJHJLtaZYhP"
Generiere UUIDs
prng.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594" prng.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab" Random.uuid #=> "f14e0271-de96-45cc-8911-8910292a42cd"
Alle Methoden sind auch in der Standardbibliothek SecureRandom verfügbar
SecureRandom.hex #=> "05b45376a30c67238eb93b16499e50cf"
Generiere eine Zufallszahl im gegebenen Bereich, wie Random es tut
prng.random_number #=> 0.5816771641321361 prng.random_number(1000) #=> 485 prng.random_number(1..6) #=> 3 prng.rand #=> 0.5816771641321361 prng.rand(1000) #=> 485 prng.rand(1..6) #=> 3
Constants
- ALPHANUMERIC
-
Die Standardzeichenliste für
alphanumeric.
Öffentliche Instanzmethoden
Source
# File lib/random/formatter.rb, line 367 def alphanumeric(n = nil, chars: ALPHANUMERIC) n = 16 if n.nil? choose(chars, n) end
Generiere eine zufällige alphanumerische Zeichenfolge.
Das Argument n gibt die Länge der zu generierenden alphanumerischen Zeichenfolge in Zeichen an. Das Argument chars gibt die Zeichenliste an, aus der sich das Ergebnis zusammensetzt.
Wenn n nicht angegeben ist oder nil ist, wird standardmäßig 16 angenommen. In Zukunft kann dies größer sein.
Das Ergebnis kann A-Z, a-z und 0-9 enthalten, es sei denn, chars ist angegeben.
require 'random/formatter' Random.alphanumeric #=> "2BuBuLf3WfSKyQbR" # or prng = Random.new prng.alphanumeric(10) #=> "i6K93NdqiH" Random.alphanumeric(4, chars: [*"0".."9"]) #=> "2952" # or prng = Random.new prng.alphanumeric(10, chars: [*"!".."/"]) #=> ",.,++%/''."
Source
# File lib/random/formatter.rb, line 114 def base64(n=nil) [random_bytes(n)].pack("m0") end
Generiere eine zufällige Base64-Zeichenfolge.
Das Argument n gibt die Länge der zu generierenden Zufallszahl in Bytes an. Die Länge der resultierenden Zeichenfolge beträgt etwa 4/3 von n.
Wenn n nicht angegeben ist oder nil ist, wird standardmäßig 16 angenommen. In Zukunft kann dies größer sein.
Das Ergebnis kann A-Z, a-z, 0-9, „+“, „/“ und „=“ enthalten.
require 'random/formatter' Random.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A==" # or prng = Random.new prng.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
Siehe RFC 3548 für die Definition von Base64.
Source
# File lib/random/formatter.rb, line 92 def hex(n=nil) random_bytes(n).unpack1("H*") end
Generiere 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 ist doppelt so groß wie n.
Wenn n nicht angegeben ist oder nil ist, wird standardmäßig 16 angenommen. In Zukunft kann dies größer sein.
Das Ergebnis kann 0-9 und a-f enthalten.
require 'random/formatter' Random.hex #=> "eb693ec8252cd630102fd0d0fb7c3485" # or prng = Random.new prng.hex #=> "91dc3bfb4de5b11d029d376634589b61"
Generiert formatierte Zufallszahlen aus rohen Zufallsbytes. Siehe Random#rand.
Source
# File lib/random/formatter.rb, line 71 def random_bytes(n=nil) n = n ? n.to_int : 16 gen_random(n) end
Generiere eine zufällige Binärzeichenfolge.
Das Argument n gibt die Länge der Ergebniszeichenfolge an.
Wenn n nicht angegeben ist oder nil ist, wird standardmäßig 16 angenommen. In Zukunft kann dies größer sein.
Das Ergebnis kann jedes Byte enthalten: „x00“ - „xff“.
require 'random/formatter' Random.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6" # or prng = Random.new prng.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
Source
static VALUE
rand_random_number(int argc, VALUE *argv, VALUE obj)
{
rb_random_t *rnd = try_get_rnd(obj);
VALUE v = rand_random(argc, argv, obj, rnd);
if (NIL_P(v)) v = rand_random(0, 0, obj, rnd);
else if (!v) invalid_argument(argv[0]);
return v;
}
Generiert formatierte Zufallszahlen aus rohen Zufallsbytes. Siehe Random#rand.
Source
# File lib/random/formatter.rb, line 145 def urlsafe_base64(n=nil, padding=false) s = [random_bytes(n)].pack("m0") s.tr!("+/", "-_") s.delete!("=") unless padding s end
Generiere eine zufällige URL-sichere Base64-Zeichenfolge.
Das Argument n gibt die Länge der zu generierenden Zufallszahl in Bytes an. Die Länge der resultierenden Zeichenfolge beträgt etwa 4/3 von n.
Wenn n nicht angegeben ist oder nil ist, wird standardmäßig 16 angenommen. In Zukunft kann dies größer sein.
Das boolesche Argument padding gibt die Auffüllung an. Wenn es false oder nil ist, wird keine Auffüllung generiert. Andernfalls wird eine Auffüllung generiert. Standardmäßig wird keine Auffüllung generiert, da „=“ als URL-Trennzeichen verwendet werden kann.
Das Ergebnis kann A-Z, a-z, 0-9, „-“ und „_“ enthalten. „=“ wird ebenfalls verwendet, wenn padding true ist.
require 'random/formatter' Random.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg" # or prng = Random.new prng.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg" prng.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ==" prng.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
Siehe RFC 3548 für die Definition von URL-sicherem Base64.
Source
# File lib/random/formatter.rb, line 169 def uuid ary = random_bytes(16) ary.setbyte(6, (ary.getbyte(6) & 0x0f) | 0x40) ary.setbyte(8, (ary.getbyte(8) & 0x3f) | 0x80) ary.unpack("H8H4H4H4H12").join(?-) end
Generiere eine zufällige v4 UUID (Universally Unique IDentifier).
require 'random/formatter' Random.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594" Random.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab" # or prng = Random.new prng.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
Die UUID der Version 4 ist rein zufällig (außer der Version). Sie enthält keine aussagekräftigen Informationen wie MAC-Adressen, Zeitstempel usw.
Das Ergebnis enthält 122 zufällige Bits (15,25 zufällige Bytes).
Siehe RFC9562 für Details zu UUIDv4.
Source
# File lib/random/formatter.rb, line 246 def uuid_v7(extra_timestamp_bits: 0) case (extra_timestamp_bits = Integer(extra_timestamp_bits)) when 0 # min timestamp precision ms = Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond) rand = random_bytes(10) rand.setbyte(0, rand.getbyte(0) & 0x0f | 0x70) # version rand.setbyte(2, rand.getbyte(2) & 0x3f | 0x80) # variant "%08x-%04x-%s" % [ (ms & 0x0000_ffff_ffff_0000) >> 16, (ms & 0x0000_0000_0000_ffff), rand.unpack("H4H4H12").join("-") ] when 12 # max timestamp precision ms, ns = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond) .divmod(1_000_000) extra_bits = ns * 4096 / 1_000_000 rand = random_bytes(8) rand.setbyte(0, rand.getbyte(0) & 0x3f | 0x80) # variant "%08x-%04x-7%03x-%s" % [ (ms & 0x0000_ffff_ffff_0000) >> 16, (ms & 0x0000_0000_0000_ffff), extra_bits, rand.unpack("H4H12").join("-") ] when (0..12) # the generic version is slower than the special cases above rand_a, rand_b1, rand_b2, rand_b3 = random_bytes(10).unpack("nnnN") rand_mask_bits = 12 - extra_timestamp_bits ms, ns = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond) .divmod(1_000_000) "%08x-%04x-%04x-%04x-%04x%08x" % [ (ms & 0x0000_ffff_ffff_0000) >> 16, (ms & 0x0000_0000_0000_ffff), 0x7000 | ((ns * (1 << extra_timestamp_bits) / 1_000_000) << rand_mask_bits) | rand_a & ((1 << rand_mask_bits) - 1), 0x8000 | (rand_b1 & 0x3fff), rand_b2, rand_b3 ] else raise ArgumentError, "extra_timestamp_bits must be in 0..12" end end
Generiere eine zufällige v7 UUID (Universally Unique IDentifier).
require 'random/formatter' Random.uuid_v7 # => "0188d4c3-1311-7f96-85c7-242a7aa58f1e" Random.uuid_v7 # => "0188d4c3-16fe-744f-86af-38fa04c62bb5" Random.uuid_v7 # => "0188d4c3-1af8-764f-b049-c204ce0afa23" Random.uuid_v7 # => "0188d4c3-1e74-7085-b14f-ef6415dc6f31" # |<--sorted-->| |<----- random ---->| # or prng = Random.new prng.uuid_v7 # => "0188ca51-5e72-7950-a11d-def7ff977c98"
Die UUID der Version 7 beginnt mit den niederwertigsten 48 Bits eines 64-Bit-Unix-Zeitstempels (Millisekunden seit der Epoche) und füllt die verbleibenden Bits mit zufälligen Daten, ausgenommen der Versions- und Variant-Bits.
Dadurch können UUIDs der Version 7 nach der Erstellungszeit sortiert werden. Time-sortierte UUIDs können für eine bessere Datenbankindex-Lokalität neu eingefügter Datensätze verwendet werden, was erhebliche Leistungsvorteile gegenüber dem Einfügen zufälliger Daten haben kann.
Das Ergebnis enthält 74 zufällige Bits (9,25 zufällige Bytes).
Beachten Sie, dass diese Methode nicht reproduzierbar gemacht werden kann, da ihre Ausgabe nicht nur Zufallsbits, sondern auch den Zeitstempel enthält.
Siehe RFC9562 für Details zu UUIDv7.
Monotonie
UUIDv7 hat standardmäßig Millisekundenpräzision, sodass mehrere UUIDs, die innerhalb derselben Millisekunde erstellt werden, nicht in monoton steigender Reihenfolge ausgegeben werden. Um UUIDs zu erstellen, die mit Sub-Millisekunden-Präzision zeitlich geordnet sind, können bis zu 12 zusätzliche Zeitstempel-Bits mit extra_timestamp_bits hinzugefügt werden. Die zusätzliche Zeitstempelpräzision geht auf Kosten von Zufallsbits. Das Setzen von extra_timestamp_bits: 12 bietet eine Präzision von etwa 244 ns, aber nur 62 Zufallsbits (7,75 Zufallsbytes).
prng = Random.new Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 12) } # => ["0188d4c7-13da-74f9-8b53-22a786ffdd5a", "0188d4c7-13da-753b-83a5-7fb9b2afaeea", "0188d4c7-13da-754a-88ea-ac0baeedd8db", "0188d4c7-13da-7557-83e1-7cad9cda0d8d"] # |<--- sorted --->| |<-- random --->| Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 8) } # => ["0188d4c7-3333-7a95-850a-de6edb858f7e", "0188d4c7-3333-7ae8-842e-bc3a8b7d0cf9", # <- out of order "0188d4c7-3333-7ae2-995a-9f135dc44ead", # <- out of order "0188d4c7-3333-7af9-87c3-8f612edac82e"] # |<--- sorted -->||<---- random --->|
Jegliche Rücksetzungen der Systemuhr brechen die Monotonie. UUIDv7 basiert auf UTC, das Schaltsekunden ausschließt und die Uhr zurücksetzen kann. Um dies zu vermeiden, kann die Systemuhr mit einem NTP-Server synchronisiert werden, der so konfiguriert ist, dass er einen „Leap Smear“-Ansatz verwendet. NTP oder PTP sind ebenfalls erforderlich, um verteilte Knoten zu synchronisieren.
Zähler und andere Mechanismen für stärkere Monotonie-Garantien sind nicht implementiert. Anwendungen mit strengeren Anforderungen sollten Abschnitt 6.2 der Spezifikation befolgen.
Private Instanzmethoden
Source
# File lib/random/formatter.rb, line 312 def choose(source, n) size = source.size m = 1 limit = size while limit * size <= 0x100000000 limit *= size m += 1 end result = ''.dup while m <= n rs = random_number(limit) is = rs.digits(size) (m-is.length).times { is << 0 } result << source.values_at(*is).join('') n -= m end if 0 < n rs = random_number(limit) is = rs.digits(size) if is.length < n (n-is.length).times { is << 0 } else is.pop while n < is.length end result.concat source.values_at(*is).join('') end result end
Generiere eine Zeichenfolge, die zufällig aus einem Quellarray von Zeichen zieht.
Das Argument source gibt das Array von Zeichen an, aus dem die Zeichenfolge generiert werden soll. Das Argument n gibt die Länge der zu generierenden Zeichenfolge in Zeichen an.
Das Ergebnis kann beliebige Zeichen aus dem Quellarray enthalten.
require 'random/formatter' prng.choose([*'l'..'r'], 16) #=> "lmrqpoonmmlqlron" prng.choose([*'0'..'9'], 5) #=> "27309"
Source
# File lib/random/formatter.rb, line 294 def gen_random(n) self.bytes(n) end
Internes Interface zu Random; Generiere n Bytes zufälliger Daten.