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.