Je génère actuellement une chaîne majuscule pseudo-aléatoire de 8 caractères pour "A" .. "Z":
value = ""; 8.times{value << (65 + Rand(25)).chr}
mais cela n'a pas l'air propre et il ne peut pas être passé comme argument puisqu'il ne s'agit pas d'une seule déclaration. Pour obtenir une chaîne de casse mixte "a" .. "z" plus "A" .. "Z", je l'ai changée en:
value = ""; 8.times{value << ((Rand(2)==1?65:97) + Rand(25)).chr}
mais cela ressemble à une corbeille.
Est-ce que quelqu'un a une meilleure méthode?
(0...8).map { (65 + Rand(26)).chr }.join
Je passe trop de temps à jouer au golf.
(0...50).map { ('a'..'z').to_a[Rand(26)] }.join
Et un dernier qui est encore plus déroutant, mais plus flexible et gaspille moins de cycles:
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[Rand(o.length)] }.join
Pourquoi ne pas utiliser SecureRandom?
require 'securerandom'
random_string = SecureRandom.hex
# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)
SecureRandom dispose également de méthodes pour:
voir: http://Ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
J'utilise ceci pour générer des chaînes amicales d'URL aléatoires avec une longueur maximale garantie:
Rand(36**length).to_s(36)
Il génère des chaînes aléatoires de minuscules a-z 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 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
D'autres ont mentionné quelque chose de similaire, mais cela utilise la fonction URL safe.
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 A-Z, a-z, 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 I O)).sample(8).join
Génère une chaîne aléatoire de 8 caractères (par exemple 3PH4SWF2), à l'exclusion de 0/1/I/O. Ruby 1.9
Depuis Ruby 2.5 vraiment facile avec SecureRandom.alphanumeric
:
len = 8
SecureRandom.alphanumeric(len)
=> "larHSsgL"
Génère des chaînes aléatoires contenant A-Z, a-z 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 également être un avantage.
Edit: Un benchmark à comparer avec la solution ayant le plus de votes positifs:
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)
Donc, la solution Rand
ne prend que 3/4 du temps de SecureRandom
. Cela peut avoir de l'importance si vous générez beaucoup de chaînes, mais si vous créez simplement une chaîne aléatoire de temps en temps, j'utiliserais toujours une implémentation plus sécurisée (car elle est également plus facile à appeler et plus explicite).
Je ne me souviens plus où j'ai trouvé cela, mais cela me semble être le meilleur et le moins intensif en processus:
def random_string(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'
randomstring = SecureRandom.hex(n)
Il va générer une chaîne aléatoire de longueur 2n
contenant 0-9
et a-f
Array.new(n){[*"0".."9"].sample}.join
, where n = 8 dans votre cas.
Généralisé: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
, etc. - from this answer
require 'sha1'
srand
seed = "--#{Rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]
Voici un code simple en ligne pour une chaîne aléatoire de longueur 8
random_string = ('0'..'z').to_a.shuffle.first(8).join
Vous pouvez également l'utiliser pour un mot de passe aléatoire d'une longueur de 8.
random_password = ('0'..'z').to_a.shuffle.first(8).join
j'espère que ça va aider 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"
Sachez que Rand
est prévisible pour un attaquant et donc probablement non sécurisé. Vous devez absolument utiliser SecureRandom s’il s’agit de 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
Voici un code simple pour mot de passe aléatoire de longueur 8
Rand_password=('0'..'z').to_a.shuffle.first(8).join
J'espère que ça va aider.
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
Quelque chose de Devise
Il suffit d'ajouter mes cents ici ...
def random_string(length = 8)
Rand(32**length).to_s(32)
end
vous pouvez utiliser String#random
à partir des facettes de Ruby Gem facets
:
il fait essentiellement ceci:
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
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 équilibre 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 nombre de personnages vraiment impressionnant:
characters = (32..126).to_a.pack('U*').chars.to_a
Mon préféré est (:A..:Z).to_a.shuffle[0,8].join
. Notez que Shuffle requiert Ruby> 1.9.
Donné:
chars = [*('a'..'z'),*('0'..'9')].flatten
Une seule expression, pouvant être passée en argument, permet les doublons de caractères:
Array.new(len) { chars.sample }.join
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 joyau random_token
pour générer des jetons aléatoires pour la plupart des cas d'utilisation, profitez ~
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
Je faisais quelque chose comme ceci 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, a-z, A-Z. J'avais un tableau d'entre eux en boucle 8 fois et en sélectionnant une valeur aléatoire dans le tableau. C'était à l'intérieur d'une application 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 bon nombre de doublons. Maintenant, au hasard, cela ne devrait pratiquement jamais arriver. 62 ^ 8 est énorme, mais sur 1 200 environ, les codes de la base de données comportaient un bon nombre de doublons. J'ai remarqué qu'ils se passaient à des limites horaires les unes des autres. En d'autres termes, je pourrais voir un duple à 12:12:23 et 2:12:22 ou quelque chose du genre ... je ne sais pas si le temps est compté ou pas.
Ce code était dans le précédent créer d'un objet activerecord. Avant la création de l'enregistrement, ce code était exécuté et générait le code "unique". Les entrées dans la base de données étaient toujours produites de manière fiable, mais le code (str dans la ligne ci-dessus) était dupliqué beaucoup trop souvent.
J'ai créé un script pour parcourir 100 000 itérations de cette ligne ci-dessus avec un léger retard, de sorte que cela prendrait 3-4 heures dans l'espoir de voir une sorte de motif de répétition sur une base horaire, mais je ne voyais rien. Je ne sais pas pourquoi cela se passait dans mon application Rails.
Si vous êtes sous UNIX et que vous devez toujours utiliser Ruby 1.8 (pas de SecureRandom) sans Rails, vous pouvez également utiliser ceci:
random_string = `openssl Rand -base64 24`
Notez que cela engendre un nouveau Shell, cela est très lent et cela ne peut être recommandé que pour les scripts.
Une autre astuce qui fonctionne avec Ruby 1.8+ et qui est rapide est:
>> require "openssl"
>> OpenSSL::Random.random_bytes(20).unpack('H*').join
=> "2f3ff53dd712ba2303a573d9f9a8c1dbc1942d28"
Vous obtenez une chaîne hexagonale aléatoire. De la même manière, vous devriez pouvoir générer une chaîne base64 ('M *').
J'aime mieux la réponse de Radar, jusqu'à présent, je pense. Je Tweak un peu comme ça:
CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def Rand_string(length=8)
s=''
length.times{ s << CHARS[Rand(CHARS.length)] }
s
end
Avec cette méthode, vous pouvez transmettre une longueur arbitraire. Il est défini par défaut sur 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
Mon meilleur coup, 2 solutions pour une chaîne aléatoire composée de 3 plages
(('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)*""
essayez ceci
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
J'aime les réponses du fil, ont été très utiles, en effet !, mais si je peux dire, aucun d'entre eux ne satisfait mes oui, peut-être la méthode Rand (). ça ne me semble tout simplement pas juste, puisque nous avons la méthode de choix Array # pour cette question.
Voici une autre méthode:
Besoins 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
Ceci est basé sur quelques autres réponses, mais cela ajoute un peu plus de complexité:
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
Cela garantit essentiellement un mot de passe de 8 à 20 caractères, contenant au moins un chiffre et un caractère spécial.
Pour la clé secure_validatable, vous pouvez utiliser cette
(0 ... 8) .map {([65, 97] .sample + Rand (26)). Chr} .Push (Rand (99)). Join
Voici une amélioration de la réponse de @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
Sur @Travis R, les caractères de réponse et les chiffres étaient ensemble, donc parfois random_string
pouvait ne renvoyer que des nombres ou des caractères. Avec cette amélioration, au moins la moitié de random_string
seront des caractères et les autres seront des nombres. Juste au cas où vous auriez besoin d'une chaîne aléatoire avec des chiffres et des caractères
Pour faire votre première déclaration dans une déclaration:
(0...8).collect { |n| value << (65 + Rand(25)).chr }.join()
Le moyen le plus simple est d'utiliser string_pattern gem https://github.com/MarioRuiz/string_pattern
Par exemple, pour générer 36 lettres aléatoires:
require 'string_pattern'
puts '36:L'.gen
Aussi, vous pouvez utiliser des expressions régulières
require 'string_pattern'
puts /[a-zA-Z]{36}/.gen
Créez une chaîne vide ou un préfixe si besoin:
myStr = "OID-"
Utilisez ce code pour renseigner la chaîne avec des nombres aléatoires:
begin; n = ((Rand * 43) + 47).ceil; myStr << n.chr if !(58..64).include?(n); end while(myStr.length < 12)
Remarques:
(Rand * 43) + 47).ceil
Il va générer des nombres aléatoires de 48 à 91 (0,1,2..Y, Z)
!(58..64).include?(n)
Il est utilisé pour ignorer les caractères spéciaux (je ne suis pas intéressé à les inclure)
while(myStr.length < 12)
Il générera une chaîne totale de 12 caractères incluant le préfixe.
Exemple de sortie:
"OID-XZ2J32XM"
a='';8.times{a<<[*'a'..'z'].sample};p a
ou
8.times.collect{[*'a'..'z'].sample}.join
Nous utilisons cela sur notre code:
class String
def self.random(length=10)
('a'..'z').sort_by {Rand}[0,length].join
end
end
La longueur maximale prise en charge est de 25 (nous l'utilisons uniquement avec la valeur par défaut, donc cela n'a pas posé de problème).
Quelqu'un a mentionné que 'a' .. 'z' est sous-optimal si vous voulez éviter complètement de générer des mots offensants. L'une de nos idées était de supprimer les voyelles, mais vous vous retrouvez toujours avec WTFBBQ, etc.
`pwgen 8 1`.chomp
Voici une solution flexible qui permet des dupes:
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
Exemple:
"ATCG".random(8) => "CGTGAAGA"
Vous pouvez également autoriser un certain caractère à apparaître plus fréquemment:
"AAAAATCG".random(10) => "CTGAAAAAGC"
Explication: La méthode ci-dessus prend les caractères d'une chaîne donnée et génère un tableau assez grand. Il le mélange ensuite, prend les n premiers éléments, puis les joint.
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
Utilisez 'SafeRandom' Gem GithubLink
Il constituera le moyen le plus simple de générer des valeurs aléatoires pour la compatibilité de Rails2, Rails 3, Rails 4 et Rails 5.