No momento, estou gerando uma sequência maiúscula pseudo-aleatória de 8 caracteres para "A" .. "Z":
value = ""; 8.times{value << (65 + rand(25)).chr}
mas não parece limpo e não pode ser passado como argumento, pois não é uma declaração única. Para obter uma sequência de maiúsculas e minúsculas "a" .. "z" mais "A" .. "Z", mudei para:
value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr}
mas parece lixo.
Alguém tem um método melhor?
reset_user_password!(random_string)
wheredef random_string; SecureRandom.urlsafe_base64(20) end
securerandom.urlsafe_base64
Respostas:
Eu gasto muito tempo jogando golfe.
E um último que é ainda mais confuso, mas mais flexível e gasta menos ciclos:
fonte
('a'..'z').to_a.shuffle[0,8].join
. Observe que você precisará do Ruby> = 1.9 parashuffle
.SecureRandom
como um exemplo, nas outras respostas.[*('a'..'z'),*('0'..'9')].shuffle[0,8].join
para gerar uma sequência aleatória com letras e números.rand
é determinístico e previsível. Não use isso para gerar senhas! Use uma dasSecureRandom
soluções.Por que não usar o SecureRandom?
O SecureRandom também possui métodos para:
consulte: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
fonte
require 'securerandom'
para obter esta arrumadoSecureRandom
ajudante :)SecureRandom.random_number(36**12).to_s(36).rjust(12, "0")
irá gerar uma sequência com 0-9a-z (36 caracteres) que SEMPRE terá 12 caracteres. Mude 12 para o tamanho que desejar. Infelizmente, não há como usar o AZInteger#to_s
.+fGH1
por um URL, basta codificá-lo como qualquer valor que estiver passando por um URL:%2BfGH1
Eu uso isso para gerar seqüências amigáveis de URL aleatórias com um comprimento máximo garantido:
Ele gera seqüências aleatórias de az minúsculas e 0-9. Não é muito personalizável, mas é curto e limpo.
fonte
rand.to_s
; feio, mas funciona.length
comprimento, aproximadamente uma vez em ~ 40(36**(length-1) + rand(36**length)).to_s(36)
. 36 ** (comprimento-1) convertido na base 36 é 10 ** (comprimento-1), que é o menor valor que tem o comprimento do dígito desejado.(36**(length-1) + rand(36**length - 36**(length-1))).to_s(36)
NameError: undefined local variable or method
comprimento' para principal: Object`Esta solução gera uma cadeia de caracteres facilmente legíveis para códigos de ativação; Não queria que as pessoas confundissem 8 com B, 1 com I, 0 com O, L com 1, etc.
fonte
SecureRandom.random_number(charset.size)
vez derand(charset.size)
%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 ! @ # $ % ^ & * +}
e%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 ! @ # $ % ^ & * }
(a primeira lista não inclui letras minúsculas, mas é mais longa) deu certo.Outros mencionaram algo semelhante, mas isso usa a função segura de URL.
O resultado pode conter AZ, az, 0-9, "-" e "_". "=" Também é usado se o preenchimento for verdadeiro.
fonte
Desde o Ruby 2.5, é realmente fácil com
SecureRandom.alphanumeric
:Ele gera seqüências aleatórias contendo AZ, az e 0-9 e, portanto, deve ser aplicável na maioria dos casos de uso. E eles são gerados aleatoriamente seguros, o que também pode ser um benefício.
Esta é uma referência para compará-la com a solução com mais votos positivos:
Portanto, a
rand
solução leva apenas cerca de 3/4 do tempo deSecureRandom
. Isso pode importar se você gerar muitas strings, mas se você criar algumas strings aleatórias de vez em quando, eu sempre utilizarei uma implementação mais segura, pois também é mais fácil chamar e mais explícito.fonte
Gere uma sequência aleatória de 8 letras (por exemplo, NVAYXHGR)
Gere uma sequência aleatória de 8 caracteres (por exemplo, 3PH4SWF2), excluindo 0/1 / I / O. Ruby 1.9
fonte
[*("A".."Z")]'
; ((qoutes não únicos))stub
issorspec
?Não me lembro onde encontrei isso, mas parece o melhor e o menos intensivo para mim:
fonte
0
e1
eO
eI
estavam intencionalmente ausentes porque esses caracteres são ambíguos. Se esse tipo de código estiver sendo usado para gerar um conjunto de caracteres que um usuário precisa copiar, é melhor excluir caracteres que podem ser difíceis de distinguir fora de contexto.fonte
Random.new.bytes(9)
n=9 ; SecureRandom.urlsafe_base64(n)[0..n-1]
Se você deseja uma sequência de comprimento especificado, use:
Irá gerar uma sequência aleatória de comprimento
2n
contendo0-9
ea-f
fonte
n
, na verdade gera uma sequência com 4/3 den
..hex
2n. Documentação: SecureRandom.hex gera uma sequência hexadecimal aleatória. O argumento n especifica o comprimento, em bytes, do número aleatório a ser gerado. O comprimento da sequência hexadecimal resultante é duas vezes de n .Array.new(n){[*"0".."9"].sample}.join
, onden=8
no seu caso.Generalizado:,
Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
etc.De: " Gere a seqüência pseudo-aleatória AZ, 0-9 ".
fonte
fonte
Aqui está um código simples de uma linha para sequência aleatória com comprimento 8:
Você também pode usá-lo para senha aleatória com tamanho 8:
fonte
P(36, 8) / 36^8 = 0.4
o espaço de caracteres possível para 8 caracteres (~ 2x mais fácil para a força bruta) ouP(36, 25) / 36^25 = 0.00001
o espaço possível para 25 caracteres (~ 100.000x mais fácil para a força bruta).Ruby 1.9+:
fonte
map
solução é muito boa!#sample
quantos elementos deseja. Por exemploALPHABET.sample(10).join
... ruby-doc.org/core-2.4.0/Array.html#method-i-samplesample(10)
fornece 10 amostras únicas. Mas você deseja permitir que eles se repitam. Mas eu usariaArray.new(10).map
para performanceArray.new
e sua sintaxe de bloco.Array.new(20) { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join
Esteja ciente:
rand
é previsível para um invasor e, portanto, provavelmente inseguro. Você definitivamente deve usar o SecureRandom se isso for para gerar senhas. Eu uso algo como isto:fonte
Aqui está um código simples para senha aleatória com comprimento 8:
fonte
Outro método que eu gosto de usar:
Adicione
ljust
se você é realmente paranóico sobre o comprimento correto da string:fonte
Algo do Devise
fonte
.tr('+/=lIO0', 'pqrsxyz')
?Penso que este é um bom equilíbrio entre concisão, clareza e facilidade de modificação.
Modificado facilmente
Por exemplo, incluindo dígitos:
Hexadecimal maiúsculo:
Para uma variedade verdadeiramente impressionante de caracteres:
fonte
Apenas adicionando meus centavos aqui ...
fonte
rand
Você pode usar
String#random
as Facets of Ruby Gemfacets
.Basicamente, faz isso:
fonte
O meu favorito é
(:A..:Z).to_a.shuffle[0,8].join
. Observe que o shuffle requer Ruby> 1.9.fonte
Essa solução precisa de dependência externa, mas parece mais bonita que outra.
Faker::Lorem.characters(10) # => "ang9cbhoa8"
fonte
Dado:
Expressão única, pode ser transmitida como argumento, permite caracteres duplicados:
fonte
Eu gosto da resposta do Radar melhor, até agora, eu acho. Eu mexeria um pouco assim:
fonte
(CHARS*length).sample(length).join
?CHARS=['a','b']
, em seguida, o seu método geraria"aa"
ou"bb"
apenas 33% do tempo, mas"ab"
ou"ba"
67% do tempo. Talvez isso não seja um problema, mas vale a pena ter em mente!fonte
Meus 2 centavos:
fonte
Acabei de escrever uma pequena gema
random_token
para gerar tokens aleatórios para a maioria dos casos de uso, aproveite ~https://github.com/sibevin/random_token
fonte
2 soluções para uma sequência aleatória composta por 3 intervalos:
Um personagem de cada intervalo.
E se você precisar de pelo menos um caractere de cada intervalo, como criar uma senha aleatória com uma letra maiúscula, uma letra minúscula e um dígito, faça algo assim:
fonte
( ('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"
Eu estava fazendo algo assim recentemente para gerar uma sequência aleatória de 8 bytes de 62 caracteres. Os caracteres eram 0-9, az, AZ. Eu tinha uma matriz deles como estava repetindo 8 vezes e escolhendo um valor aleatório fora da matriz. Isso foi dentro de um aplicativo Rails.
O estranho é que consegui um bom número de duplicatas. Agora, aleatoriamente, isso quase nunca deve acontecer. 62 ^ 8 é enorme, mas em cerca de 1200 códigos no db eu tinha um bom número de duplicatas. Eu os notei acontecendo nos limites das horas um do outro. Em outras palavras, eu posso ver um duplo em 12:12:23 e 2:12:22 ou algo assim ... não tenho certeza se o tempo é o problema ou não.
Esse código estava na criação anterior de um objeto ActiveRecord. Antes da criação do registro, esse código seria executado e geraria o código 'exclusivo'. As entradas no banco de dados sempre foram produzidas com confiabilidade, mas o código (
str
na linha acima) estava sendo duplicado com muita frequência.Criei um script para executar 100000 iterações dessa linha acima com um pequeno atraso, de modo que levaria de 3 a 4 horas na esperança de ver algum tipo de padrão de repetição a cada hora, mas não vi nada. Não tenho idéia do por que isso estava acontecendo no meu aplicativo Rails.
fonte