如何在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-9
和af
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
:
它基本上这样做:
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需要外部依赖,但看起来比另一个漂亮。
- 安装gem福克
-
Faker::Lorem.characters(10) # => "ang9cbhoa8"
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
我只是写了一个小的gem 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