我目前正在为"a"生成一个8个字符的伪随机大写字符串。Z:
1
| value =""; 8.times{value << (65 + rand(25)).chr} |
但它看起来不干净,而且不能作为参数传递,因为它不是一条语句。要获得混合大小写字符串"a"……Z"加上"A"…"Z",我改为:
1
| value =""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr} |
但它看起来像垃圾。
有人有更好的方法吗?
1
| (0...8).map { (65 + rand(26)).chr }.join |
我花了太多时间打高尔夫球。
1
| (0...50).map { ('a'..'z').to_a[rand(26)] }.join |
最后一个更混乱,但更灵活,浪费更少的周期:
1 2
| o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join |
为什么不使用SecureRandom?
1 2 3 4
| require 'securerandom'
random_string = SecureRandom.hex
# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f) |
SecureRandom还具有以下方法:
参见:http://ruby-doc.org/stdlib-1.9.2/libdoc/securelrandom/rdoc/securelrandom.html
我使用它生成随机的URL友好字符串,保证最大长度:
1
| rand(36**length).to_s(36) |
它生成小写a-z和0-9的随机字符串。它不是很可定制,但它又短又干净。
这个解决方案为激活代码生成一个易于阅读的字符串;我不希望人们混淆8与B、1与I、0与O、L与1等。
1 2 3 4 5
| # 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 A C D E F G H J K M N P Q R T V W X Y Z}
(0...size).map{ charset.to_a[rand(charset.size)] }.join
end |
其他人也提到了类似的内容,但这使用了URL安全功能。
1 2 3 4
| require 'securerandom'
p SecureRandom.urlsafe_base64(5) #=>"UtM7aa8"
p SecureRandom.urlsafe_base64 #=>"UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=>"i0XQ-7gglIsHGV2_BNPrdQ==" |
结果可能包含a-z、a-z、0-9、"-"和"uu"。如果padding为true,则也使用"="。
1
| [*('A'..'Z')].sample(8).join |
生成随机8个字母的字符串(例如nvayxhgr)
1
| ([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(8).join |
生成一个随机的8个字符串(例如3ph4swf2),不包括0/1/i/o.ruby 1.9
因为很容易与SecureRandom.alphanumeric:红宝石。
1 2 3
| len = 8
SecureRandom.alphanumeric(len)
=>"larHSsgL" |
随机字符串生成含Z、Z、0—9,因此,应该是最适用的案件中使用。他们是随机生成的和安全的,这可能是有益的,太。
编辑:基准的解决方案,它具有相对最upvotes:
1 2 3 4 5 6 7 8 9 10 11 12 13
| require 'benchmark'
require 'securerandom'
len = 10
n = 100_000
Benchmark.bm(12) do |x|
x.report('SecureRandom') { n.times { SecureRandom.alphanumeric(len) } }
x.report('rand') do
o = [('a'..'z'), ('A'..'Z'), (0..9)].map(&:to_a).flatten
n.times { (0...len).map { o[rand(o.length)] }.join }
end
end |
1 2 3
| user system total real
SecureRandom 0.429442 0.002746 0.432188 ( 0.432705)
rand 0.306650 0.000716 0.307366 ( 0.307745) |
解决方案:操作系统的rand仅约3 / 4的时间SecureRandom。可如果你真的会产生很多的字符串,如果你只是创建了一些随机的字符串,从时间,以时间,我总是去实现更安全的(因为它是更容易和更明确的呼唤也)。
我不记得在哪里找到的,但对我来说,这似乎是最好和最不需要过程的:
1 2 3 4 5 6
| def random_string(length=10)
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
password = ''
length.times { password << chars[rand(chars.size)] }
password
end |
1 2
| require 'securerandom'
SecureRandom.urlsafe_base64(9) |
如果需要指定长度的字符串,请使用:
1 2
| require 'securerandom'
randomstring = SecureRandom.hex(n) |
它将生成包含0-9和a-f的长度为2n的随机字符串。
Array.new(n){[*"0".."9"].sample}.join;其中n=8。
广义的:Array.new(n){[*"A".."Z", *"0".."9"].sample}.join等。——来自这个答案
1 2 3 4
| require 'sha1'
srand
seed ="--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8] |
红宝石1.9 +:
1 2 3 4 5 6 7 8 9 10
| 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的随机字符串
1
| random_string = ('0'..'z').to_a.shuffle.first(8).join |
您也可以将其用于长度为8的随机密码
1
| random_password = ('0'..'z').to_a.shuffle.first(8).join |
我希望它会有帮助,令人惊叹。
下面是一个简单的随机密码代码,使用lenth 8
1
| rand_password=('0'..'z').to_a.shuffle.first(8).join |
希望能有所帮助。
注意:对于攻击者来说,rand是可预测的,因此可能不安全。如果这是为了生成密码,则绝对应该使用SecureRandom。我用这样的东西:
1 2 3 4 5 6
| 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 |
我喜欢用的另一种方法
1
| rand(2**256).to_s(36)[0..7] |
添加ljust如果您真的对正确的字符串长度有疑虑:
1
| rand(2**256).to_s(36).ljust(8,'a')[0..7] |
1
| SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') |
设计的东西
我认为这是一个简洁、清晰和易于修改的很好的平衡。
1 2 3
| characters = ('a'..'z').to_a + ('A'..'Z').to_a
# Prior to 1.9, use .choice, not .sample
(0..8).map{characters.sample}.join |
容易修改的
例如,包括数字:
1
| characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a |
大写十六进制:
1
| characters = ('A'..'F').to_a + (0..9).to_a |
对于一系列真正令人印象深刻的人物:
1
| characters = (32..126).to_a.pack('U*').chars.to_a |
您可以从ruby gem facets的方面使用String#random:
https://github.com/rubyworks/facets/blob/126a619fd766bc5588cac18d09c4f1927538e33/lib/core/facets/string/random.rb
基本上是这样的:
1 2 3 4 5 6 7
| 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 |
只是在这里加我的分…
1 2 3
| def random_string(length = 8)
rand(32**length).to_s(32)
end |
这个解决方案需要外部依赖,但看起来比另一个更好。
安装gem faker
Faker::Lorem.characters(10) # =>"ang9cbhoa8"
鉴于:
1
| chars = [*('a'..'z'),*('0'..'9')].flatten |
单个表达式可以作为参数传递,允许重复字符:
1
| Array.new(len) { chars.sample }.join |
我最喜欢的是(:A..:Z).to_a.shuffle[0,8].join。注意,无序播放需要Ruby>1.9。
我只写了一个小gem random_token,为大多数用例生成随机令牌,享受~
https://github.com/sibevin/random_令牌
我最近做了这样的工作,从62个字符中生成一个8字节的随机字符串。字符是0-9,a-z,a-z。我有一个它们的数组,循环8次,从数组中选择一个随机值。这是在一个Rails应用程序中。
str = ''
8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }
奇怪的是我有很多副本。现在随机地,这应该是永远不会发生的。62^8是巨大的,但在数据库中大约1200个代码中,我有很多重复的。我注意到它们发生在彼此的时间界限上。换言之,我可能会在12:12:23和2:12:22看到一个二重唱或类似的事情……不确定时间是否是问题所在。
此代码位于创建ActiveRecord对象之前。在创建记录之前,此代码将运行并生成"唯一"代码。数据库中的条目总是可靠地生成的,但是代码(上面一行中的str)被复制得太频繁了。
我创建了一个脚本,用很小的延迟运行上面这行的100000次迭代,所以需要3-4个小时,希望每小时看到某种重复模式,但什么也没有看到。我不知道为什么在我的Rails应用程序中会发生这种情况。
我的2分钱:
1 2 3 4
| def token(length=16)
chars = [*('A'..'Z'), *('a'..'z'), *(0..9)]
(0..length).map {chars.sample}.join
end |
1
| ''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} } |
试试这个
1 2 3 4 5 6 7 8 9
| def rand_name(len=9)
ary = [('0'..'9').to_a, ('a'..'z').to_a, ('A'..'Z').to_a]
name = ''
len.times do
name << ary.choice.choice
end
name
end |
我喜欢这条线的答案,真的很有帮助!但是如果我可以说,它们中没有一个满足我的条件,可能是rand()方法。我觉得这不太合适,因为我们已经有了数组选择方法。
我认为,到目前为止,我最喜欢雷达的回答。我会这样调整一下:
1 2 3 4 5 6
| CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
s=''
length.times{ s << CHARS[rand(CHARS.length)] }
s
end |
用这种方法,你可以通过一个小长度。默认设置为6。
1 2 3 4 5 6 7 8
| def generate_random_string(length=6)
string =""
chars = ("A".."Z").to_a
length.times do
string << chars[rand(chars.length-1)]
end
string
end |
Ruby1.8+的另一个技巧是:
1 2 3
| >> require"openssl"
>> OpenSSL::Random.random_bytes(20).unpack('H*').join
=>"2f3ff53dd712ba2303a573d9f9a8c1dbc1942d28" |
它得到的是你随机的十六进制字符串。类似地,您应该能够生成base64字符串("m*")。
我的最佳镜头,3个范围的随机字符串的2个解决方案
1 2 3
| (('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a).sample(8).join
([*(48..57),*(65..90),*(97..122)]).sample(8).collect(&:chr)*"" |
如果您在Unix上,并且您仍然必须使用Ruby1.8(非SecureRandom)而不使用Rails,那么您也可以使用它:
1
| random_string = `openssl rand -base64 24` |
注意,这会生成新的shell,速度非常慢,只能推荐用于脚本。
另一种方法是:
- 它使用安全随机数生成器而不是rand()。
- 可用于URL和文件名
- 包含大写、小写字符和数字
- 具有不包含不明确字符的选项i0l01
需要EDOCX1[0]
1 2 3 4 5 6 7 8 9 10 11
| def secure_random_string(length = 32, non_ambiguous = false)
characters = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
%w{I O 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 |
为了设计安全的,你可以使用这个
(0…8).map([65,97].sample+rand(26)).chr.push(rand(99)).join
这是基于其他一些答案,但它增加了一点复杂性:
1 2 3 4 5 6 7 8 9 10 11 12 13
| def random_password
specials = ((32..47).to_a + (58..64).to_a + (91..96).to_a + (123..126).to_a).pack('U*').chars.to_a
numbers = (0..9).to_a
alpha = ('a'..'z').to_a + ('A'..'Z').to_a
%w{i I l L 1 O o 0}.each{ |ambiguous_character|
alpha.delete ambiguous_character
}
characters = (alpha + specials + numbers)
password = Random.new.rand(8..18).times.map{characters.sample}
password << specials.sample unless password.join =~ Regexp.new(Regexp.escape(specials.join))
password << numbers.sample unless password.join =~ Regexp.new(Regexp.escape(numbers.join))
password.shuffle.join
end |
基本上,它确保密码的长度为8-20个字符,并且至少包含一个数字和一个特殊字符。
1 2 3 4
| 10.times do
alphabet = ('a'..'z').to_a
string += alpha[rand(alpha.length)]
end |
以下是一个灵活的解决方案,允许重复数据消除:
1 2 3 4 5 6 7
| class String
# generate a random string of length n using current string as the source of characters
def random(n)
return"" if n <= 0
(chars * (n / length + 1)).shuffle[0..n-1].join
end
end |
例子:
1
| "ATCG".random(8) =>"CGTGAAGA" |
您还可以允许某个字符更频繁地出现:
1
| "AAAAATCG".random(10) =>"CTGAAAAAGC" |
说明:上面的方法获取给定字符串的字符并生成足够大的数组。然后对其进行无序处理,获取前n个项,然后将它们联接起来。
1 2 3 4 5
| Array.new(8).inject(""){|r|r<<('0'..'z').to_a.shuffle[0]} # 57
(1..8).inject(""){|r|r<<('0'..'z').to_a.shuffle[0]} # 51
e="";8.times{e<<('0'..'z').to_a.shuffle[0]};e # 45
(1..8).map{('0'..'z').to_a.shuffle[0]}.join # 43
(1..8).map{rand(49..122).chr}.join # 34 |
如果需要,请创建空字符串或预修复:
使用此代码用随机数填充字符串:
1
| begin; n = ((rand * 43) + 47).ceil; myStr << n.chr if !(58..64).include?(n); end while(myStr.length < 12) |
笔记:
它将从48-91(0,1,2..y,z)生成随机数。
它用于跳过特殊字符(因为我不想包括它们)
1
| while(myStr.length < 12) |
它将生成总共12个字符长的字符串,包括前缀。
样品输出:
该方法是使用easiest字符串模式的创业板_ https:/ / / / _ github.com marioruiz字符串模式
例如:36生成随机字母
1 2
| require 'string_pattern'
puts '36:L'.gen |
也可以使用正则表达式
1 2
| require 'string_pattern'
puts /[a-zA-Z]{36}/.gen |
把你的第一句话写成一句话:
1
| (0...8).collect { |n| value << (65 + rand(25)).chr }.join() |
1
| a='';8.times{a<<[*'a'..'z'].sample};p a |
或
1
| 8.times.collect{[*'a'..'z'].sample}.join |
我们在代码中使用了这个:
1 2 3 4 5 6 7
| class String
def self.random(length=10)
('a'..'z').sort_by {rand}[0,length].join
end
end |
支持的最大长度是25(我们只在默认情况下使用它,所以没有问题)。
有人提到,如果你想完全避免产生冒犯性的词语,"a"…"z"是次优的。我们的一个想法是去掉元音,但是你最终还是得到了wtfbq等等。
在这里,R是(答案:提高"特拉维斯
1 2 3 4 5 6 7 8
| def random_string(length=5)
chars = 'abdefghjkmnpqrstuvwxyzABDEFGHJKLMNPQRSTUVWXYZ'
numbers = '0123456789'
random_s = ''
(length/2).times { random_s << numbers[rand(numbers.size)] }
(length - random_s.length).times { random_s << chars[rand(chars.size)] }
random_s.split('').shuffle.join
end |
"特拉维斯(R)和答案的字符数在一起,所以有时可以返回random_string仅只数或字符。这提高了至少一半的与random_string)是将字符和数字。如果你需要的只是在案件的随机数和字符的字符串。
使用"githublink saferandom宝石
它将提供easiest生成随机值的方式是rails2 Rails,Rails的3,4,5上的兼容。
这几乎是丑陋的,但也许是正确的方向?
1
| (1..8).map{|i| ('a'..'z').to_a[rand(26)]}.join |
在Ruby1.9中,可以使用数组的choice方法,该方法从数组中返回随机元素。
我不知道Ruby,所以我不能给出确切的语法,但是我会用可接受字符列表设置一个常量字符串,然后使用substring操作符从中选择一个随机字符。
这里的优点是,如果字符串应该是用户可输入的,那么您可以排除容易混淆的字符,如l和1、i、0和o、5和s等。