在Ruby中创建一些可读的单词

时间:2016-12-22 19:45:39

标签: ruby ruby-2.3

我试图在ruby中创建一些包含大写,小写,数字和特殊字符的可读单词,如:

FlAshmnger!2
Derfing$23

要在ruby中创建随机字符串,您可以执行以下操作:

lower = ('a'...'z').to_a
upper = ('A'...'Z').to_a
numbers = (0...9).to_a
specs = %w(! ? * ^ $)
size = 8

charset = [lower, upper, numbers, specs].flatten
(0...size).map { charset[rand(charset.size)] }.join
#<= ?!VVQUjH
#<= ^tsm^Led

有没有办法可以确保随机字符串有点可读?包含常数,元音等。使用特殊字符和至少一个数字而不使用外部宝石?

2 个答案:

答案 0 :(得分:1)

从头开始创建密码

gist为基础:

class PasswordGenerator
  # Original version : https://gist.github.com/lpar/1031933
  # Simple generation of readable random passwords using Ruby
  # by lpar

  # These are the koremutake syllables, plus the most common 2 and 3 letter 
  # syllables taken from the most common 5,000 words in English, minus a few
  # syllables removed so that combinations cannot generate common rude
  # words in English.
  SYLLABLES = %w(ba be bi bo bu by da de di do du dy fe fi fo fu fy ga ge gi
        go gu gy ha he hi ho hu hy ja je ji jo ju jy ka ke ko ku ky la le li lo 
        lu ly ma me mi mo mu my na ne ni no nu ny pa pe pi po pu py ra re ri ro 
        ru ry sa se si so su sy ta te ti to tu ty va ve vi vo vu vy bra bre bri 
        bro bru bry dra dre dri dro dru dry fra fre fri fro fru fry gra gre gri 
        gro gru gry pra pre pri pro pru pry sta ste sti sto stu sty tra tre er 
        ed in ex al en an ad or at ca ap el ci an et it ob of af au cy im op co 
        up ing con ter com per ble der cal man est for mer col ful get low son 
        tle day pen pre ten tor ver ber can ple fer gen den mag sub sur men min 
        out tal but cit cle cov dif ern eve hap ket nal sup ted tem tin tro tro)

  def initialize
    srand
  end

  def generate(length)
    result = ''
    while result.length < length
      syl = SYLLABLES[rand(SYLLABLES.length)]
      result += syl
    end
    result = result[0,length]
    # Stick in a symbol
    spos = rand(length)
    result[spos,1] = %w(! ? * ^ $).sample
    # Stick in a digit, possibly over the symbol
    dpos = rand(length)
    result[dpos,1] = rand(9).to_s
    # Make a letter capitalized
    cpos = rand(length)
    result[cpos,1] = result[cpos,1].swapcase
    return result
  end
end

pwgen = PasswordGenerator.new

10.times do
  puts pwgen.generate(10)
end

输出示例:

Mageve$7ur
Pehu5ima^r
a!hub8osta
b5gobrY^er
miN!e3inyf
manb1ufr^p
d^m0ndeRca
Ter5esur$b
m8r$omYket
gyso5it^le

使用pwgen

您也可以安装pwgen并使用:

%x(pwgen).chomp
#=> "aipeebie"

以及更复杂的密码:

%x(pwgen --symbols --numerals --capitalize #{length}).chomp
#=> "Ma[Foh1EeX"

更正马电池订书钉

根据此XKCD漫画的推荐,您可以从字典中选择4个常用字词(例如/usr/share/dict/american-english)。

答案 1 :(得分:0)

使用..代替...稍微更正您的范围,这包括每个范围中的最终元素:

lower = ('a'..'z').to_a
upper = ('A'..'Z').to_a
numbers = (0..9).to_a
specs = %w(! ? * ^ $)

charset = [lower, upper, numbers, specs]

然后说如果你想从每个字符集中说两个,你可以像这样使用Enumerable#inject

charset.inject([]) { |memo,obj| memo + obj.sample(2) }.shuffle.join
#=> "Lf5^$O2u"

更多自定义:

def rand_string (l,u,n,s)
  (('a'..'z').to_a.sample(l) +
   ('A'..'Z').to_a.sample(u) +
   (0..9).to_a.sample(n)     +
   %w(! ? * ^ $).sample(s)).shuffle.join
end

然后加权随机字符串包含3个低位字母,3个大写字母,3个数字和1个特殊字符:

rand_string(3,3,3,1)
#=> "ic!I04OEr7"