Je suis actuellement en train de générer une chaîne majuscule pseudo-aléatoire de 8 caractères pour “A” .. “Z”:
value = ""; 8.times{value << (65 + rand(25)).chr}
mais il ne semble pas propre, et il ne peut pas être transmis en tant qu’argument, car il ne s’agit pas d’une seule déclaration. Pour obtenir une chaîne de caractères “a” .. “z” plus “A” .. “Z”, je l’ai changé pour:
value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr}
mais ça ressemble à des ordures.
Est-ce que quelqu’un a une meilleure méthode?
(0...8).map { (65 + rand(26)).chr }.join
Je passe trop de temps au golf.
(0...50).map { ('a'..'z').to_a[rand(26)] }.join
Et un dernier qui est encore plus déroutant, mais plus souple et gaspille moins de cycles:
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten ssortingng = (0...50).map { o[rand(o.length)] }.join
Pourquoi ne pas utiliser SecureRandom?
require 'securerandom' random_ssortingng = SecureRandom.hex # outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (ie 32 chars of 0..9, a..f)
SecureRandom a également des méthodes pour:
voir: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
Je l’utilise pour générer des chaînes aléatoires avec une longueur maximale garantie:
rand(36**length).to_s(36)
Il génère des chaînes aléatoires de minuscules az et 0-9. Ce n’est pas très personnalisable mais c’est court et propre.
Cette solution génère une chaîne de caractères facilement lisibles pour les codes d’activation; Je ne voulais pas que les gens confondent 8 avec B, 1 avec I, 0 avec O, L avec 1, etc.
# Generates a random ssortingng from a set of easily readable characters def generate_activation_code(size = 6) charset = %w{ 2 3 4 6 7 9 ACDEFGHJKMNPQRTVWXYZ} (0...size).map{ charset.to_a[rand(charset.size)] }.join end
D’autres ont mentionné quelque chose de similaire, mais cela utilise la fonction URL sécurisée.
require 'securerandom' p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8" p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg" p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
Le résultat peut contenir AZ, az, 0-9, “-” et “_”. “=” Est également utilisé si le remplissage est vrai.
[*('A'..'Z')].sample(8).join
Générer une chaîne aléatoire de 8 lettres (par exemple NVAYXHGR)
([*('A'..'Z'),*('0'..'9')]-%w(0 1 IO)).sample(8).join
Générer une chaîne de caractères aléatoire de 8 caractères (par exemple 3PH4SWF2), exclut 0/1 / I / O. Ruby 1.9
Je ne me souviens plus où j’ai trouvé cela, mais cela me semble être le meilleur et le moins intensif:
def random_ssortingng(length=10) chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789' password = '' length.times { password << chars[rand(chars.size)] } password end
require 'securerandom' SecureRandom.urlsafe_base64(9)
Si vous voulez une chaîne de longueur spécifiée, utilisez:
require 'securerandom' randomssortingng = SecureRandom.hex(n)
Il générera une chaîne aléatoire de longueur 2n
contenant 0-9
et af
Depuis ruby 2.5 vraiment facile avec SecureRandom.alphanumeric
:
len = 8 SecureRandom.alphanumeric(len) => "larHSsgL"
Génère des chaînes aléatoires contenant AZ, az et 0-9 et devrait donc être applicable dans la plupart des cas d’utilisation. Et ils sont générés de manière aléatoire, ce qui pourrait être un avantage.
Edit: Un benchmark pour le comparer avec la solution ayant le plus de votes:
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)
La solution rand
ne prend donc que les SecureRandom
de SecureRandom
. Peu importe si vous générez vraiment beaucoup de chaînes, mais si vous créez simplement une chaîne aléatoire de temps en temps, j’utiliserai toujours une implémentation plus sécurisée (car elle est également plus facile à appeler et plus explicite).
Array.new(n){[*"0".."9"].sample}.join
, où n = 8 dans votre cas.
Généralisé: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
, etc. – de cette réponse
require 'sha1' srand seed = "--#{rand(10000)}--#{Time.now}--" Digest::SHA1.hexdigest(seed)[0,8]
Voici un code simple de ligne pour une chaîne aléatoire de longueur 8
random_ssortingng = ('0'..'z').to_a.shuffle.first(8).join
Vous pouvez également l’utiliser pour un mot de passe aléatoire de longueur 8
random_password = ('0'..'z').to_a.shuffle.first(8).join
J’espère que cela aidera et incroyable.
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"
Voici un code simple pour mot de passe aléatoire avec lenth 8
rand_password=('0'..'z').to_a.shuffle.first(8).join
J’espère que ça va aider.
Sachez que le rand
est prévisible pour un attaquant et donc probablement non sécurisé. Vous devez absolument utiliser SecureRandom pour générer des mots de passe. J’utilise quelque chose comme ça:
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
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
Quelque chose de Devise
Une autre méthode que j’aime utiliser
rand(2**256).to_s(36)[0..7]
Ajoutez Ljust si vous êtes vraiment paranoïaque à propos de la longueur de chaîne correcte:
rand(2**256).to_s(36).ljust(8,'a')[0..7]
Je pense que c’est un bon compromis entre concision, clarté et facilité de modification.
characters = ('a'..'z').to_a + ('A'..'Z').to_a # Prior to 1.9, use .choice, not .sample (0..8).map{characters.sample}.join
Par exemple, y compris les chiffres:
characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
Hexadécimal majuscule:
characters = ('A'..'F').to_a + (0..9).to_a
Pour un éventail de caractères vraiment impressionnant:
characters = (32..126).to_a.pack('U*').chars.to_a
Il suffit d’append mes cents ici …
def random_ssortingng(length = 8) rand(32**length).to_s(32) end
vous pouvez utiliser Ssortingng#random
des facettes Facettes of Ruby Gem:
il fait essentiellement ceci:
class Ssortingng 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
Mon préféré est (:A..:Z).to_a.shuffle[0,8].join
. Notez que la lecture aléatoire nécessite Ruby> 1.9.
Cette solution nécessite une dépendance externe, mais semble plus belle qu’une autre.
Faker::Lorem.characters(10) # => "ang9cbhoa8"
Donné:
chars = [*('a'..'z'),*('0'..'9')].flatten
L’expression unique, pouvant être transmise en tant qu’argument, autorise les doublons:
Array.new(len) { chars.sample }.join
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
Mes 2 centimes:
def token(length=16) chars = [*('A'..'Z'), *('a'..'z'), *(0..9)] (0..length).map {chars.sample}.join end
Je viens d’écrire un petit bijou random_token
pour générer des jetons aléatoires pour la plupart des cas d’utilisation, profitez de ~
Avec cette méthode, vous pouvez passer dans une longueur différente. Il est défini par défaut sur 6.
def generate_random_ssortingng(length=6) ssortingng = "" chars = ("A".."Z").to_a length.times do ssortingng << chars[rand(chars.length-1)] end string end
J’aime mieux la réponse de Radar, jusqu’à présent, je pense. Je modifierais un peu comme ceci:
CHARS = ('a'..'z').to_a + ('A'..'Z').to_a def rand_ssortingng(length=8) s='' length.times{ s << CHARS[rand(CHARS.length)] } s end
Je faisais quelque chose comme ça récemment pour générer une chaîne aléatoire de 8 octets à partir de 62 caractères. Les caractères étaient 0-9, az, AZ. J’avais un tableau d’entre eux comme il était en boucle 8 fois et en choisissant une valeur aléatoire dans le tableau. C’était dans une application de rails.
str = '' 8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }
La chose étrange est que j'ai eu un bon nombre de doublons. Maintenant, au hasard, cela ne devrait jamais se produire. 62 ^ 8 est énorme, mais sur environ 1200 codes dans la firebase database, j'avais un bon nombre de doublons. Je les ai remarqués se produire aux heures les uns des autres. En d'autres termes, je pourrais voir un dupe à 12:12:23 et 2:12:22 ou quelque chose comme ça… je ne sais pas si le temps est le problème ou pas.
Ce code était dans la création avant d'un object activerecord. Avant la création de l'enregistrement, ce code s'exécutait et générait le code "unique". Les entrées dans la firebase database étaient toujours produites de manière fiable, mais le code (str dans la ligne ci-dessus) était copié beaucoup trop souvent.
J'ai créé un script pour parcourir 100 000 itérations de la ligne ci-dessus avec un léger retard, ce qui prendrait 3 à 4 heures dans l'espoir de voir un motif de répétition toutes les heures, mais sans rien voir. Je ne sais pas pourquoi cela se passait dans mon application rails.