Wait the light to fall

🎄 1/25. 在 Raku 中生成随机密码

焉知非鱼

欢迎来到全新的 Raku.Online Advent Calendar 的第1天!今年,它的主题是 Raku One-Liners(来自 raku.onliners 的双关语)。因此,欢迎参加今年的 Raku One-Liner Advent Calendar。整个 raku.online 博客最初计划每天一篇,因此这是一个很好的机会,可以保持 25天每天一篇。

不要忘记关注其他人编写的其他与 Perl 相关的日历:

在接下来的几天里,我将发表简短的文章,要么解释 Raku Calendar 2019 的代码,要么解决 Project Euler 启发的一些问题,Raku 可以展示它的极致美感(如果你不想看到我的答案)在你之前,我邀请你先自己解决这些任务,然后再阅读这些文章。但是今天,让我们从其他东西开始,在 Raku 中生成一个随机密码。

这是完整的代码:

('0'..'z').pick(15).join.say

运行几次:

Z4x72B8wkWHo0QD
J;V?=CE84jIS^r9
2;m6>kdHRS04XEL
O6wK=umZ]DqyHT5
3SP\tNkX5Zh@1C4
PX6QC?KdWYyzNOc
bq1EfBZNdK9vHxz

每次运行时,我们的这行代码都会生成不同的字符串。如果您尚未安装 Raku,请自行尝试创建密码或使用上述密码之一。

前段时间,我们研究了pick方法的内部结构。它在Any类中定义,它实际上是将工作代理给List类的方法:

proto method pick(|) is nodal {*}
multi method pick() { self.list.pick }
multi method pick($n) { self.list.pick($n) }

join 方法也在 List 类中定义。我们现在不要检查它的主体,因为它很大,但让我们来看看签名:

method join(List:D: Str(Cool) $separator = '') is nodal

可以清楚地看到,当调用不带参数的方法时,默认分隔符是一个空字符串,这正是我们对密码所需要的。(在文档中了解有is nodal trait的更多信息;据说在特殊代码中不应该广泛使用该特征。)

您也可以问一个问题:我可以期望密码中有哪些字符?你问的好极了! Raku 是面向 Unicode 的语言,范围 '0'..'z' 似乎包含具有不同 Unicode 属性的字符(即,至少是数字和字母)。要查看其中的内容,只需从我们今天的代码中删除 pick 方法:

('0'..'z').join.say

此行在两个给定字符之间打印 ASCII 表的子集:

0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
abcdefghijklmnopqrstuvwxyz

这些是可能出现在密码中的字符。 pick 方法确保不重复字符。

这就是今天的全部,明天再看另一行 Raku 代码。