Как создать случайное 10-значное число в рубине? - PullRequest
57 голосов
/ 29 августа 2008

Кроме того, как я могу отформатировать ее как строку, дополненную нулями?

Ответы [ 20 ]

79 голосов
/ 29 августа 2008

Для генерации номера звоните rand с результатом выражения «10 в степени 10»

rand(10 ** 10)

Чтобы дополнить число нулями, вы можете использовать оператор форматирования строки

'%010d' % rand(10 ** 10)

или rjust метод строки

rand(10 ** 10).to_s.rjust(10,'0')  
51 голосов
/ 10 августа 2013

Я хотел бы предложить, пожалуй, самое простое из известных мне решений, и это неплохой трюк.

rand.to_s[2..11] 
 => "5950281724"
26 голосов
/ 04 марта 2016

Это быстрый способ создания строки цифр размером 10:

10.times.map{rand(10)}.join # => "3401487670"
13 голосов
/ 25 июня 2015

Самый простой ответ, вероятно, будет

rand(1e9...1e10).to_i

Часть to_i необходима, потому что 1e9 и 1e10 фактически являются плавающими:

irb(main)> 1e9.class
=> Float
7 голосов
/ 11 апреля 2017

Генерация случайных чисел

Использование Kernel # rand Метод:

rand(1_000_000_000..9_999_999_999) # => random 10-digits number

Генерация случайной строки

Используйте комбинацию times + map + join:

10.times.map { rand(0..9) }.join # => random 10-digit string (may start with 0!)

Преобразование числа в строку с заполнением

Использовать Строка #% Метод:

"%010d" % 123348 # => "0000123348"

Генерация пароля

Используйте Генератор паролей KeePass Библиотека, она поддерживает различные шаблоны для генерации случайного пароля:

KeePass::Password.generate("d{10}") # => random 10-digit string (may start with 0!)

Документацию по шаблонам KeePass можно найти здесь .

7 голосов
/ 13 сентября 2013

Просто потому, что он не был упомянут, метод Kernel#sprintf (или его псевдоним Kernel#format в Powerpack Library ) обычно предпочтительнее метода String#%, как упоминалось в Ruby Community Style Guide .

Конечно, это очень спорно, но, чтобы обеспечить понимание:

Синтаксис ответа @ quackingduck будет

# considered bad
'%010d' % rand(10**10)

# considered good
sprintf('%010d', rand(10**10))

Природа этого предпочтения в первую очередь обусловлена ​​загадочной природой %. Сам по себе он не очень семантический, и без какого-либо дополнительного контекста его можно спутать с оператором % по модулю.

Примеры из Руководства по стилю :

# 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'

Если судить по String#%, мне лично очень нравится использовать операторные синтаксисы вместо команд, так же, как вы делаете your_array << 'foo' поверх your_array.push('123').

Это просто иллюстрирует тенденцию в сообществе, что «лучшее» зависит от вас.

Подробнее в этом блоге .

6 голосов
/ 26 мая 2015

НЕ ИСПОЛЬЗОВАТЬ rand.to_s[2..11].to_i

Почему? Потому что вот что вы можете получить:

rand.to_s[2..9] #=> "04890612"

и затем:

"04890612".to_i #=> 4890612

Обратите внимание, что:

4890612.to_s.length #=> 7

Чего ты не ожидал!

Чтобы проверить эту ошибку в своем собственном коде, вместо .to_i вы можете обернуть ее так:

Integer(rand.to_s[2..9])

и очень скоро получится, что:

ArgumentError: invalid value for Integer(): "02939053"

Так что всегда лучше придерживаться .center, но имейте в виду, что:

rand(9) 

иногда может дать вам 0.

Чтобы предотвратить это:

rand(1..9)

, который всегда будет возвращать что-то в диапазоне 1..9.

Я рад, что у меня были хорошие тесты, и я надеюсь, что вы избежите поломки вашей системы.

3 голосов
/ 12 июля 2012

Я просто хочу изменить первый ответ. rand (10**10) может генерировать 9-значный случайный номер, если 0 стоит на первом месте. Для обеспечения 10 точных цифр просто измените

code = rand(10**10)
while code.to_s.length != 10
code = rand(11**11)

конец

2 голосов
/ 12 октября 2016

Простейший способ генерирования случайного числа из n цифр -

Random.new.rand((10**(n - 1))..(10**n))

сгенерировать 10-значный номер -

Random.new.rand((10**(10 - 1))..(10**10))
2 голосов
/ 06 октября 2008

Вот выражение, которое будет использовать на один вызов метода меньше, чем в примере с quackingduck.

'%011d' % rand(1e10)

Одно предупреждение, 1e10 - это Float, и Kernel#rand заканчивает тем, что вызывает to_i, так что для некоторых более высоких значений могут возникнуть некоторые несоответствия. Чтобы быть более точным с литералом, вы также можете сделать:

'%011d' % rand(10_000_000_000) # Note that underscores are ignored in integer literals
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...