的另一种方法:
string = "this is a test"
subs = [{"a"=>"@"}, {"i"=>"!"}, {"s"=>"$"}]
subs.repeated_combination(subs.size)
.map {|e| string.gsub(/./) {|c| (g = e.find {|h| h.key?(c)}) ? g[c] : c}}
.uniq
#=> ["this is @ test", "th!s !s @ test", "thi$ i$ @ te$t", "th!$ !$ @ te$t",
# "th!s !s a test", "th!$ !$ a te$t", thi$ i$ a te$t"]
说明:
a = subs.repeated_combination(subs.size)
# Enumerator...
a.to_a
# [[{"a"=>"@"},{"a"=>"@"},{"a"=>"@"}], [{"a"=>"@"},{"a"=>"@"},{"i"=>"!"}],
# [{"a"=>"@"},{"a"=>"@"},{"s"=>"$"}], [{"a"=>"@"},{"i"=>"!"},{"i"=>"!"}],
# [{"a"=>"@"},{"i"=>"!"},{"s"=>"$"}], [{"a"=>"@"},{"s"=>"$"},{"s"=>"$"}],
# [{"i"=>"!"},{"i"=>"!"},{"i"=>"!"}], [{"i"=>"!"},{"i"=>"!"},{"s"=>"$"}],
# [{"i"=>"!"},{"s"=>"$"},{"s"=>"$"}], [{"s"=>"$"},{"s"=>"$"},{"s"=>"$"}]]
b = a.map {|e| string.gsub(/./) {|c| (g = e.find {|h| h.key?(c)}) ? g[c] : c}}
#=> ["this is @ test", "th!s !s @ test", "thi$ i$ @ te$t", "th!s !s @ test",
# "th!$ !$ @ te$t", "thi$ i$ @ te$t", "th!s !s a test", "th!$ !$ a te$t",
# "th!$ !$ a te$t", "thi$ i$ a te$t"]
要了解b
的计算方式,传递给该块的a
第二元件:
e = [{"a"=>"@"},{"a"=>"@"},{"i"=>"!"}]
由于该正则表达式的,/./
,gsub
传递的string
每个字符c
到块
{|c| (g = e.find {|h| h.key?(c)}) ? g[c] : c}
搜索结果由e
来确定如果三个哈希中的任何一个都有c
作为关键字。如果找到一个,即g
,则将字符c
替换为g[c]
;否则,角色保持不变。
请注意,e
的前两个元素是相同的。通过将第一行改为:
subs.repeated_combination(subs.size).map(&:uniq)
可以提高效率,但效率不是这种方法的优点之一。
返回到主计算,最后的步骤是:
b.uniq
#=> ["this is @ test", "th!s !s @ test", "thi$ i$ @ te$t", "th!$ !$ @ te$t",
# "th!s !s a test", "th!$ !$ a te$t", "thi$ i$ a te$t"]
只是好奇,为什么你要生成的组合? –
它适用于我正在使用的计算机安全课程中的任务。我们要写一个密码破解器,给出一个单词列表应该破解我们的教授给我们的散列密码。以上是已经实现的,尽管以非常难看的方式将每个组合在脚本中进行硬编码。 – user3207230
你是否需要确切的预期产出,那么我需要更多地回答我的问题? –