1

我正在尝试在包含大写、小写、数字和特殊字符的 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

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

4

2 回答 2

1

从头开始创建密码

使用这个要点作为基础:

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)。

于 2016-12-22T23:31:14.430 回答
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"
于 2016-12-22T20:39:19.667 回答