metodos - ¿Cómo puedo generar un número aleatorio de 10 dígitos en ruby?
numeros aleatorios ruby (16)
Generación aleatoria de números
Use Kernel#rand método Kernel#rand :
rand(1_000_000_000..9_999_999_999) # => random 10-digits number
Generación aleatoria de cadenas
Usar combinaciones de tiempo + combinación de map
+:
10.times.map { rand(0..9) }.join # => random 10-digit string (may start with 0!)
Conversión de número a cadena con relleno
Use String#% método String#% :
"%010d" % 123348 # => "0000123348"
Generación de contraseña
Use la biblioteca del generador de contraseñas KeePass , admite diferentes patrones para generar una contraseña aleatoria:
KeePass::Password.generate("d{10}") # => random 10-digit string (may start with 0!)
Una documentación para los patrones de KeePass se puede encontrar here .
Además, ¿cómo puedo formatearlo como una cadena rellenada con ceros?
NO USE rand.to_s[2..11].to_i
¿Por qué? Porque esto es lo que puedes obtener:
rand.to_s[2..9] #=> "04890612"
y entonces:
"04890612".to_i #=> 4890612
Tenga en cuenta que:
4890612.to_s.length #=> 7
¡Lo cual no es lo que esperabas!
Para verificar ese error en su propio código, en lugar de .to_i
puede envolverlo así:
Integer(rand.to_s[2..9])
y muy pronto resultará que:
ArgumentError: invalid value for Integer(): "02939053"
Por lo tanto, siempre es mejor quedarse con .center
, pero tenga en cuenta que:
rand(9)
a veces puede darte 0
.
Para evitar eso:
rand(1..9)
que siempre devolverá algo dentro del rango de 1..9
.
Me alegra que haya tenido buenas pruebas y espero que evites romper tu sistema.
Aquí hay una expresión que usará una llamada de método menos que el ejemplo de quackingduck.
''%011d'' % rand(1e10)
Una advertencia, 1e10
es un Float
, y Kernel#rand
termina llamando to_i
en él, por lo que para algunos valores más altos puede tener algunas inconsistencias. Para ser más preciso con un literal, también podrías hacer:
''%011d'' % rand(10_000_000_000) # Note that underscores are ignored in integer literals
Esta es una forma rápida de generar una cadena de dígitos de 10 tamaños:
10.times.map{rand(10)}.join # => "3401487670"
Esta técnica funciona para cualquier "alfabeto"
(1..10).map{"0123456789".chars.to_a.sample}.join
=> "6383411680"
Esto funcionará incluso en ruby 1.8.7:
rand (9999999999) .to_s.center (10, rand (9) .to_s) .to_i
Intente utilizar la biblioteca de ruby SecureRandom.
Genera números aleatorios pero la longitud no es específica.
Consulte este enlace para obtener más información: http://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html
La respuesta más directa sería probablemente
rand(1e9...1e10).to_i
La parte to_i
es necesaria porque 1e9
y 1e10
son realmente flotantes:
irb(main)> 1e9.class
=> Float
Manera más simple de generar número aleatorio de n dígitos -
Random.new.rand((10**(n - 1))..(10**n))
generar un número de 10 dígitos -
Random.new.rand((10**(10 - 1))..(10**10))
Me gustaría contribuir probablemente con la solución más simple que conozco, que es un truco bastante bueno.
rand.to_s[2..11]
=> "5950281724"
Para generar el número llame al rand con el resultado de la expresión "10 a la potencia de 10"
rand(10 ** 10)
Para rellenar el número con ceros puede usar el operador de formato de cadena
''%010d'' % rand(10 ** 10)
o el método rjust
de cadena
rand(10 ** 10).to_s.rjust(10,''0'')
Solo porque no fue mencionado, el método Kernel#sprintf
(o su alias Kernel#format
en la Biblioteca Powerpack ) es generalmente preferido sobre el método String#%
, como se menciona en la Guía de Ruby Community Style .
Por supuesto, esto es muy discutible, pero para proporcionar una idea:
La sintaxis de la respuesta de @ quackingduck sería
# considered bad
''%010d'' % rand(10**10)
# considered good
sprintf(''%010d'', rand(10**10))
La naturaleza de esta preferencia se debe principalmente a la naturaleza críptica de %
. No es muy semántico por sí mismo y sin ningún contexto adicional se puede confundir con el operador %
modulo.
Ejemplos de la Guía de estilo :
# bad
''%d %d'' % [20, 10]
# => ''20 10''
# good
sprintf(''%d %d'', 20, 10)
# => ''20 10''
# good
sprintf(''%{first} %{second}'', first: 20, second: 10)
# => ''20 10''
format(''%d %d'', 20, 10)
# => ''20 10''
# good
format(''%{first} %{second}'', first: 20, second: 10)
# => ''20 10''
Para hacer justicia al String#%
, personalmente me gusta usar sintaxis similares a operadores en lugar de comandos, de la misma manera que harías your_array << ''foo''
sobre your_array.push(''123'')
.
Esto solo ilustra una tendencia en la comunidad, lo que es "lo mejor" depende de usted.
Más información en este blogpost .
Solo quiero modificar la primera respuesta. rand (10**10)
puede generar 9 dígitos al azar no si 0 está en primer lugar. Para garantizar 10 dígitos exactos solo modifique
code = rand(10**10)
while code.to_s.length != 10
code = rand(11**11)
fin
Un mejor enfoque es usar Array.new()
lugar de .times.map
. Rubocop lo recomienda.
Ejemplo:
string_size = 9
Array.new(string_size) do
rand(10).to_s
end
Rubucop, TimesMap:
https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Performance/TimesMap
Una respuesta alternativa, utilizando la gema ruby de expresiones regulares:
require ''regexp-examples''
//d{10}/.random_example # => "0826423747"
No hay necesidad de "rellenar con ceros" con este enfoque, ya que está generando inmediatamente una String
.
rand(9999999999).to_s.center(10, rand(9).to_s).to_i
es más rápido que
rand.to_s[2..11].to_i
Puedes usar:
puts Benchmark.measure{(1..1000000).map{rand(9999999999).to_s.center(10, rand(9).to_s).to_i}}
y
puts Benchmark.measure{(1..1000000).map{rand.to_s[2..11].to_i}}
en la consola de Rails para confirmar eso.