在这篇文章中,我们检查了一个拍摄了一串字母的Bash脚本,以各种可能的方式重新排列并检查每个排列以识别那些是英语单词的字符串。在此过程中,我们将仔细查看脚本并计算它可能需要的努力。
注意,在使用的算法中,每个字母的排列都必须使用全部提供的字符串中的字母。不考虑由子串形成的单词。
首先,脚本希望将被打乱的字符串作为参数提供,如果没有提供参数,则会提示它。然后,它检查每一个字母的排列,以找到那些存在于系统中字文件 - 在这种情况下,这是/usr/share/dict/words。以下是脚本中的第一行:
#!/ bin / bash如果[$#== 0];然后echo-n“乱乱的字符串>”读取串elst = $ 1 fi
该脚本的下一部分定义了一个函数,它们都会重新排列字母并查找匹配项字文件。如果数组不包含匹配项,则匹配项将被添加到数组中。
功能混合{如果[“$ {#1}”== 1];然后word =“$ {2} $ {1}”grep ^ $ word $ / usr / share / dict / words&> / dev / null如果[$?== 0];那么如果[[!“$ {单词[@]}”=〜“$ word”]];然后#添加Word如果新单词[$ n] = $ word((++ n))fi fi fi fi fi fi以$(seq 0 $(($ {#1} -1)));do pre =“$ {2} $ {1:$ i:1}”pc1 =“$ {1:0:$ i}”pc2 =“$ {1:$((i + 1))}”pc =“$ {PC1} $ {PC2}”MIXUP“$ PC”“$前”完成FI}
在脚本的最后一行中,混合函数首次调用。运行所需次数后,脚本显示在数组中保存的单词数,然后列出单词。
mixup $ string echo $ {#字词[@]}“在$ {lock [@]}中找到的word”。尽量回声;完毕
如果我们运行字母“olwf”的脚本,我们将获得包含三个单词的列表。
$解读olwf 3字发现狼蛛流动
响应将在第二个左右交付。
然而,关于这个剧本的最糟糕的事情是,如果你把它放在一个相当长的字符串中,就会涂上一个相当长的绳子,它会采取一个长是时候回复你了。你也可以去喝咖啡休息或早睡。使用12个字符的字符串可能听起来不像是一个大不了的事情,但这意味着你会使用12!(12个阶乘)字母的不同安排。如果你有一段时间没有使用因子,请让我提醒你12!是12 x 11 x 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2或479,001,600不同的字母安排(计算符号的字母多次上的任何重复)!脚本将为八个字符串需要几分钟,但是12个字符的字符串需要更多的时间。
要计算阶乘,您可以使用像这样的脚本:
#!/ bin / bash如果[$#== 0];然后回显--N“输入号码>”读取Num = $ 1 fi fac = 1,而[$ num -gt 1] do fac = $(fac * num))num = $((num - 1))完成回声$ fac.
当给出数字8时,脚本会告诉我们8个字符的字符串将有40320种不同的排列方式。如果再增加4个字符,我们将看到近5亿人。
$ armential 8 40320 $ factorial 12 479001600
这种差异会影响所有弦所需的时间生成和检查字文件。8个字符的字符串应该只需要几分钟运行。
$ time解读bthpaale 1 word(s)找到字母real 1m49.693s用户1m20.559s sys 0m26.921s
一个9个字符的字符串需要两倍的时间来处理吗?不,应该要九倍的时间。一个长度的字符串?将近12000(11800)倍。下面是一个使用9个字符的字符串运行的示例:
$时间解读Fialactor 1 Word(S)发现因子Real 16M27.318S用户12M1.492S SYS 4M5.169S
一个12个字符的字符串可能需要数周,除非,也许是,您刚刚使用超级计算机。
包起来
使用所描述的方法解读单词是彻底的,但是对于长单词,可能会非常慢。我怀疑网站喜欢WORDUNSCRAMBLER.正在使用相当不同的方法 - 可能利用预先生成的扰乱和解密的单词列表。
虽然我编写和使用的大多数Bash脚本都是直截了当和相当高的,但研究了解读字符串的问题使其明确表示解决问题的最逻辑方法也不是。