如何在Ruby中生成一个随机string

我目前正在为“A”生成一个8个字符的伪随机大写string..“Z”:

value = ""; 8.times{value << (65 + rand(25)).chr} 

但它看起来并不干净,不能作为一个parameter passing,因为它不是一个单一的陈述。 要得到一个混合大小写的string“a”..“z”加上“A”..“Z”,我把它改为:

 value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr} 

但它看起来像垃圾。

有没有人有更好的方法?

 (0...8).map { (65 + rand(26)).chr }.join 

我花了太多时间打高尔夫球。

 (0...50).map { ('a'..'z').to_a[rand(26)] }.join 

而最后一个更令人困惑,但更灵活,浪费更less的周期:

 o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten string = (0...50).map { o[rand(o.length)] }.join 

为什么不使用SecureRandom?

 require 'securerandom' random_string = SecureRandom.hex # outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (ie 32 chars of 0..9, a..f) 

SecureRandom也有以下方法:

  • BASE64
  • random_bytes
  • RANDOM_NUMBER

请参阅: http : //ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html

我用这个来产生随机的URL友好的string。

 rand(36**length).to_s(36) 

它会生成小写az和0-9的随机string。 这不是非常可定制的,但它很短,干净。

该解决scheme为激活码生成一串易读的字符; 我不想让人们混淆B和B,1和I,0和O,L和1等。

 # Generates a random string from a set of easily readable characters def generate_activation_code(size = 6) charset = %w{ 2 3 4 6 7 9 ACDEFGHJKMNPQRTVWXYZ} (0...size).map{ charset.to_a[rand(charset.size)] }.join end 

其他人提到了类似的东西,但是这个使用了URL安全function。

 require 'securerandom' p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8" p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg" p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ==" 

结果可能包含AZ,az,0-9,“ – ”和“_”。 如果填充为真,也使用“=”。

 [*('A'..'Z')].sample(8).join 

生成一个随机的8个字母的string(例如NVAYXHGR)

 ([*('A'..'Z'),*('0'..'9')]-%w(0 1 IO)).sample(8).join 

生成一个随机的8string(例如3PH4SWF2),不包括0/1 / I / O。 Ruby 1.9

我不记得我在哪里find这个东西,但它似乎是对我来说最好的,也是最不重要的过程:

 def random_string(length=10) chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789' password = '' length.times { password << chars[rand(chars.size)] } password end 
 require 'securerandom' SecureRandom.urlsafe_base64(9) 

如果你想要一个指定长度的string,使用:

 require 'securerandom' randomstring = SecureRandom.hex(n) 

它会产生一个长度2n的随机string,包含0-9af

 require 'sha1' srand seed = "--#{rand(10000)}--#{Time.now}--" Digest::SHA1.hexdigest(seed)[0,8] 

Array.new(n){[*"0".."9"].sample}.join ,其中n = 8。

Generalized: Array.new(n){[*"A".."Z", *"0".."9"].sample}.join等 – 从这个答案

这是一个长度为8的随机string的简单代码

  random_string = ('0'..'z').to_a.shuffle.first(8).join 

您也可以将其用于长度为8的随机密码

 random_password = ('0'..'z').to_a.shuffle.first(8).join 

我希望它会有帮助和惊人的。

Ruby 1.9+:

 ALPHABET = ('a'..'z').to_a #=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] 10.times.map { ALPHABET.sample }.join #=> "stkbssowre" # or 10.times.inject('') { |s| s + ALPHABET.sample } #=> "fdgvacnxhc" 

这里是一个简单的随机密码密码8

 rand_password=('0'..'z').to_a.shuffle.first(8).join 

希望它会有所帮助。

注意: rand对于攻击者来说是可以预测的,因此可能不安全。 如果这是为了生成密码,你一定要使用SecureRandom。 我使用这样的东西:

 length = 10 characters = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a password = SecureRandom.random_bytes(length).each_char.map do |char| characters[(char.ord % characters.length)] end.join 

我喜欢使用另一种方法

  rand(2**256).to_s(36)[0..7] 

如果你真的偏执于正确的string长度,请添加ljust:

  rand(2**256).to_s(36).ljust(8,'a')[0..7] 

我认为这是一个简洁,清晰和易于修改的好平衡。

 characters = ('a'..'z').to_a + ('A'..'Z').to_a # Prior to 1.9, use .choice, not .sample (0..8).map{characters.sample}.join 

轻松修改

例如,包括数字:

 characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a 

大写hex:

 characters = ('A'..'F').to_a + (0..9).to_a 

对于一个真正令人印象深刻的字符:

 characters = (32..126).to_a.pack('U*').chars.to_a 
 SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') 

从devise的东西

只需在这里添加我的分…

 def random_string(length = 8) rand(32**length).to_s(32) end 

你可以使用Ruby Gem facets String#random

https://github.com/rubyworks/facets/blob/126a619fd766bc45588cac18d09c4f1927538e33/lib/core/facets/string/random.rb

它基本上这样做:

 class String def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"]) characters = character_set.map { |i| i.to_a }.flatten characters_len = characters.length (0...len).map{ characters[rand(characters_len)] }.join end end 

我最喜欢的是(:A..:Z).to_a.shuffle[0,8].join 。 请注意,shuffle需要Ruby> 1.9。

这个解决scheme需要外部依赖,但看起来比另一个漂亮。

  1. 安装gem福克
  2. Faker::Lorem.characters(10) # => "ang9cbhoa8"
 ''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} } 

我只是写了一个小的gem random_token来为大多数用例生成随机令牌,享受〜

https://github.com/sibevin/random_token

鉴于:

 chars = [*('a'..'z'),*('0'..'9')].flatten 

单个expression式可以作为parameter passing,允许重复字符:

 Array.new(len) { chars.sample }.join 

用这种方法你可以传递一个abitrary长度。 它被设置为默认值6。

 def generate_random_string(length=6) string = "" chars = ("A".."Z").to_a length.times do string << chars[rand(chars.length-1)] end string end 

我认为,到目前为止,我最喜欢雷达的答案。 我有点像这样调整:

 CHARS = ('a'..'z').to_a + ('A'..'Z').to_a def rand_string(length=8) s='' length.times{ s << CHARS[rand(CHARS.length)] } s end 

我最近正在做这样的事情,从62个字符生成一个8字节的随机string。 字符是0-9,az,AZ。 我有一个数组循环8次,并从数组中挑选一个随机值。 这是在一个rails应用程序。

str = '' 8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }

奇怪的是我有很多重复的东西。 现在随机这应该几乎不会发生。 62 ^ 8是巨大的,但是在db中有1200个左右的代码,我有很多副本。 我注意到他们发生在彼此的小时界限上。 换句话说,我可能会在12:12:23和2:12:22看到一个双倍或类似的东西…不知道时间是否是问题。

这段代码是在创buildactiverecord对象之前。 在创buildlogging之前,此代码将运行并生成“唯一”代码。 数据库中的条目总是可靠地生成,但是代码(上面的str)被重复得太频繁了。

我创build了一个脚本,通过100000次以上的迭代,延迟很小,所以需要3-4小时才能看到某种重复模式,但是什么都看不到。 我不知道为什么这发生在我的Rails应用程序。

这是另一种方法:

  • 它使用安全的随机数发生器而不是rand()
  • 可以在URL和文件名中使用
  • 包含大写,小写字符和数字
  • 有一个选项不包含含糊不清的字符I0l01

需要require "securerandom"

 def secure_random_string(length = 32, non_ambiguous = false) characters = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a %w{IO l 0 1}.each{ |ambiguous_character| characters.delete ambiguous_character } if non_ambiguous (0...length).map{ characters[ActiveSupport::SecureRandom.random_number(characters.size)] }.join end 

我的2美分:

  def token(length=16) chars = [*('A'..'Z'), *('a'..'z'), *(0..9)] (0..length).map {chars.sample}.join end