【问题标题】:Random password generation with conditions有条件的随机密码生成
【发布时间】:2011-03-19 12:03:53
【问题描述】:

我正在开发一个随机密码生成器来创建满足特定条件的密码,包括但不一定限于:

  • 最小长度:必须包含至少 8 个字符
  • 小写字母:必须包含小写字母(从一组中选择,以避免字符可能被误认为数字的问题)
  • 大写字母:必须包含大写字母(同样,从一组中选择)
  • digits:必须包含数字

确保生成的密码满足所有这些要求的最佳算法方法是什么?

我不是在寻找一个完整的解决方案,我只需要一些好的想法和指南。

【问题讨论】:

标签: algorithm passwords generator


【解决方案1】:

1) 随机生成数字 L,这将是您密码的确切长度。即生成大于8
2) 随机生成一个数字 LL,它是小写字母的个数。 LC 必须在 [1..L-2] 范围内
3)随机生成大写数字LU。必须在 [1..L-LL-1] 范围内
4) LD = L-LL-LU 大写位数
5) 随机生成LL小写字母、LU大写字母和LD数字,并将它们保存在一个列表(数组)中
6) 随机打乱数组

第

【讨论】:

  • +1 我要补充一点,好的改组并非易事 :-) 这是一个使用伪代码 en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 的好算法的链接
  • @xantos: 或者,如果使用 C++,我们可以使用std::random_shuffle() 方法:)
  • 我喜欢。但是为什么不把 L 固定在 8 呢?这是在满足要求的同时最容易记住的长度。
  • “随机生成”背后隐藏着一些复杂性。如果使用统一随机数,生成的密码将不会均匀分布在符合要求的整个密码集中。例如,在 8 个字符的密码中,您平均会得到 2.25 位数字,而使用@dana 的解决方案,您将得到 1.69 位。
【解决方案2】:
  • 创建一个包含 a - z、A - Z、0 - 9 的字符数组(减去每个问题可能令人困惑的任何字符)
  • 连接数组中随机选择的 8 个字符
  • 测试结果是否满足要求
  • 如果不满足要求,重新开始

该算法通常应该在最初的几次迭代中成功,并且使您不必实施随机算法。

【讨论】:

  • 绝对!它也没有隐藏的偏见。值得注意的是,这以很高的概率很快终止(在找到可接受的解决方案之前的预期尝试次数为 1.4)。愚蠢的是,我在编写我的解决方案时没有注意到您的解决方案(相同的解决方案,但我假设随机函数产生随机字节 0x00-0xFF 并且没有费心修复范围)。
【解决方案3】:

Armen 提出的精确构造还有一个替代方案。如果你的条件很可能满足那么:

  • 得到一个无限长的随机字符串(一个流)
  • 延迟过滤可接受的字符(例如:大写 || 小写 || 数字)
  • 跨流跨步设置所需长度的窗口,当窗口属性正常时接受。

在惰性语言中,这大约是 6 行非样板代码,不需要任何改组。

编辑:是的,像在 cmets 中一样步进一个窗口,而不是滑动一个窗口。谢谢!

【讨论】:

  • 滑动窗口还是步进窗口?如果你滑动,你会偏向密码的分布,最终偏向于频率较低的字符类。假设您需要 2 个字符的密码。数字比字母少,所以典型的流看起来像abcd5efg...。当您滑动窗口时,您拒绝ab、bc、cd 并接受d5。该数字更有可能出现在第二个位置,因为一旦它滑入该位置,密码就会变得可以接受。
  • 对,您不应该真的滑动窗口,而是测试所需长度的离散块:loop input = let (s,r) = splitAt len input in if strProp s then s else loop r。信封计算的背面表明,您应该期望测试 1.4 个可能的密码以获得有效密码(8 个字符,因此生成密码平均消耗 47 个随机字节)。
猜你喜欢
  • 2010-09-08
  • 2012-11-06
  • 2022-09-23
  • 2021-12-02
  • 2015-04-13
  • 2012-07-28
  • 2011-09-05
相关资源
最近更新 更多