71

此外,如何将其格式化为用零填充的字符串?

4

23 回答 23

91

使用表达式“10 的 10 次方”的结果生成数字 call rand

rand(10 ** 10)

要用零填充数字,您可以使用字符串格式运算符

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

或者rjust字符串的方法

rand(10 ** 10).to_s.rjust(10,'0')  
于 2008-08-29T16:13:42.050 回答
63

我想贡献一个我知道的最简单的解决方案,这是一个很好的技巧。

rand.to_s[2..11] 
 => "5950281724"
于 2013-08-10T11:12:35.620 回答
34

这是生成 10 大小的数字字符串的快速方法:

10.times.map{rand(10)}.join # => "3401487670"
于 2016-03-03T23:23:04.357 回答
17

最直接的答案可能是

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

to_i部分是必需的,因为1e9并且1e10实际上是浮动的:

irb(main)> 1e9.class
=> Float
于 2015-06-25T07:24:46.243 回答
12

不要使用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范围内的东西。

我很高兴我有很好的测试,我希望你不会破坏你的系统。

于 2015-05-26T11:00:12.380 回答
11

随机数生成

使用内核#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!)

带填充的数字到字符串转换

使用String#%方法:

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

密码生成

使用KeePass 密码生成器库,它支持生成随机密码的不同模式:

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

可以在此处找到 KeePass 模式的文档。

于 2017-04-11T13:06:03.693 回答
7

正如Ruby Community Style Guide中所提到的,仅仅因为没有提及,该Kernel#sprintf方法(或者它Kernel#formatPowerpack Library中的别名)通常比该String#%方法更受欢迎。

当然,这是值得商榷的,但为了提供见解:

@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').

这只是说明了社区中的一种趋势,什么是“最好的”取决于你。

此博文中的更多信息。

于 2013-09-13T15:02:54.693 回答
5

我最终使用了 Ruby 内核srand

srand.to_s.last(10)

此处的文档:内核#srand

于 2020-08-17T15:41:01.003 回答
4

这是一个表达式,它使用的方法调用比 quackingduck 的示例少。

'%011d' % rand(1e10)

一个警告1e10是 a Float,并Kernel#rand最终调用to_i它,因此对于某些更高的值,您可能会有一些不一致的地方。为了更准确地使用文字,您还可以执行以下操作:

'%011d' % rand(10_000_000_000) # Note that underscores are ignored in integer literals
于 2008-10-06T18:52:13.017 回答
3

我只想修改第一个答案。rand (10**10)如果 0 排在第一位,可能会生成 9 位随机数。为了确保 10 个精确的数字,只需修改

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

结尾

于 2012-07-11T23:22:30.567 回答
3

尝试使用 SecureRandom ruby​​ 库。

它生成随机数,但长度不具体。

通过此链接了解更多信息:http ://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html

于 2015-06-24T08:10:31.890 回答
3

生成 n 位随机数的最简单方法 -

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

生成 10 位数字号码 -

Random.new.rand((10**(10 - 1))..(10**10))
于 2016-10-12T09:46:47.787 回答
3

('%010d' % rand(0..9999999999)).to_s

或者

"#{'%010d' % rand(0..9999999999)}"

于 2019-03-27T14:29:27.810 回答
2

此技术适用于任何“字母”

(1..10).map{"0123456789".chars.to_a.sample}.join
=> "6383411680"
于 2015-06-25T07:19:11.157 回答
2

只需在下面直接使用。

rand(10 ** 9...10 ** 10)

只需在下面的 IRB 上测试它。

(1..1000).each { puts rand(10 ** 9...10 ** 10) }
于 2018-08-29T10:39:19.233 回答
1
rand(9999999999).to_s.center(10, rand(9).to_s).to_i

rand.to_s[2..11].to_i

您可以使用:

puts Benchmark.measure{(1..1000000).map{rand(9999999999).to_s.center(10, rand(9).to_s).to_i}}

puts Benchmark.measure{(1..1000000).map{rand.to_s[2..11].to_i}}

在 Rails 控制台中确认。

于 2014-09-05T09:42:14.390 回答
1

要生成一个随机的 10 位字符串:

# This generates a 10-digit string, where the
# minimum possible value is "0000000000", and the
# maximum possible value is "9999999999"
SecureRandom.random_number(10**10).to_s.rjust(10, '0')

以下是正在发生的事情的更多细节,通过将单行分成多行并解释变量来显示:

  # Calculate the upper bound for the random number generator
  # upper_bound = 10,000,000,000
  upper_bound = 10**10

  # n will be an integer with a minimum possible value of 0,
  # and a maximum possible value of 9,999,999,999
  n = SecureRandom.random_number(upper_bound)

  # Convert the integer n to a string
  # unpadded_str will be "0" if n == 0
  # unpadded_str will be "9999999999" if n == 9_999_999_999
  unpadded_str = n.to_s

  # Pad the string with leading zeroes if it is less than
  # 10 digits long.
  # "0" would be padded to "0000000000"
  # "123" would be padded to "0000000123"
  # "9999999999" would not be padded, and remains unchanged as "9999999999"
  padded_str = unpadded_str.rjust(10, '0')
于 2019-06-12T14:10:19.323 回答
1

另一个答案,使用regexp-examplesruby​​ gem:

require 'regexp-examples'

/\d{10}/.random_example # => "0826423747"

这种方法不需要“用零填充”,因为您会立即生成一个String.

于 2017-08-02T10:48:12.897 回答
0

这甚至适用于 ruby​​ 1.8.7:

rand(9999999999).to_s.center(10, rand(9).to_s).to_i

于 2013-01-24T12:18:50.487 回答
0

在我的案例中,编号在我的模型中必须是唯一的,所以我添加了检查块。

  module StringUtil
    refine String.singleton_class do
      def generate_random_digits(size:)
        proc = lambda{ rand.to_s[2...(2 + size)] }
        if block_given?
          loop do
            generated = proc.call
            break generated if yield(generated) # check generated num meets condition
          end
        else
          proc.call
        end
      end
    end
  end
  using StringUtil
  String.generate_random_digits(3) => "763"
  String.generate_random_digits(3) do |num|
    User.find_by(code: num).nil?
  end => "689"(This is unique in Users code)
于 2019-01-21T04:23:10.363 回答
0

我做了这样的事情

x = 10  #Number of digit
(rand(10 ** x) + 10**x).to_s[0..x-1]
于 2021-04-24T20:04:30.013 回答
0

更好的方法是使用Array.new()而不是.times.map. Rubocop 推荐它。

例子:

string_size = 9
Array.new(string_size) do
   rand(10).to_s
end

Rubucop,时代地图:

https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Performance/TimesMap

于 2018-06-21T10:52:52.867 回答
-1

随机 10 个数字:

require 'string_pattern'
puts "10:N".gen
于 2018-12-06T15:25:29.617 回答