-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
82af78d
commit a0de60e
Showing
2 changed files
with
53 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# 07 | 排列:如何让计算机学会“田忌赛马”? | ||
|
||
排列:从 n 个不同的元素中取出 m(1≤m≤n)个不同的元素,按照一定顺序排成一列,就是排列。 | ||
|
||
全部的元素排列就是全排列,选出的元素允许有重复就是重复排列,否则是不重复排列。 | ||
|
||
## 排列有关计算 | ||
|
||
- 0! = 1 | ||
- 对于 n 个元素全排列,所有的不重复排列数量是 nx(n-1)x(n-2)x…x2x1,也就是 n! | ||
- 对于 n 个元素里取出 m(0<m≤n) 个元素的不重复排列数量是 nx(n-1)x(n-2)x…x(n - m + 1),也就是 n!/(n-m)! | ||
- 对于 n 个元素里取出 m(0<m≤n) 个元素的重复排列 n ^ m(指数增长) | ||
|
||
推导:n 个人排一条长度为 m 的队,第一个位置有 n 种选择,第二个是 n-1 种选择,直到最后一个 m (最大为 n)位置是 n - m + 1 种选择。 | ||
|
||
## 应用 | ||
|
||
### 田忌赛马 | ||
|
||
将田忌的赛马通过递归生成六个排列,分别跟齐王的三匹马进行对比,可以得到获胜的一组方案。 | ||
|
||
### 暴力破解 | ||
|
||
密码根据每一位可用的字符和位数可以形成一个很大的集合,理论上遍历完所有集合就可以得到当前密码。 | ||
|
||
每一位密码只能选择数字有 10 种数字,支持输入 8 位密码,可以生成 10^8 种选择,即 100M 一亿种密码组合,这样需要尝试的时间就会很长。 | ||
|
||
所以需要增加密码的字符类型和位数,降低系统试错密码的阈值,设置足够复杂和多样以及长度的密码即可防御。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const characters = ['a', 'b', 'c', 'd', 'e']; | ||
|
||
const password = 'ebea'; | ||
|
||
function guessPass(result = []) { | ||
if (result.length === 4) { | ||
console.log('trying: ', result.join('')); | ||
if (result.join('') === password) { | ||
throw result.join(''); | ||
} | ||
return; | ||
} | ||
for (let i = 0; i < characters.length; i++) { | ||
newResult = [...result]; | ||
newResult.push(characters[i]); | ||
|
||
guessPass(newResult); | ||
} | ||
} | ||
|
||
try { | ||
guessPass(); | ||
} catch (password) { | ||
console.log('get the password: ', password); | ||
} |