Go 生成所有可能的n字符密码
作为学习围棋练习的一部分,我正在编写一个简单的蛮力密码破解程序 要生成所有可能使用Python中A-E字符的2字符密码,我将使用: 然而,在围棋中我很难做到这一点 似乎是关于排列,这不是我想要的。虽然Python文档包含函数的示例实现,但我不知道如何将Go 生成所有可能的n字符密码,go,Go,作为学习围棋练习的一部分,我正在编写一个简单的蛮力密码破解程序 要生成所有可能使用Python中A-E字符的2字符密码,我将使用: 然而,在围棋中我很难做到这一点 似乎是关于排列,这不是我想要的。虽然Python文档包含函数的示例实现,但我不知道如何将yield转换为Go 我想我应该提到两个限制: 我希望密码的长度是可变的。也就是说,我可能想要8个字符的密码,或者6个字符的密码,或者其他什么。这意味着我们不能只嵌套n个循环 我不想一下子把它们都记起来 你想要的基本上是一个集合本身。因此,对于所有
yield
转换为Go
我想我应该提到两个限制:
你想要的基本上是一个集合本身。因此,对于所有需要Prod(设置、设置、设置)的3字符密码。这可以迭代地构造。首先构造n-1乘积,然后为初始集合的每个乘积和每个元素添加元素。例如,所有2个字符的密码->3个字符的密码,其中唯一有效的字符是“a”或“b”
“ab”={a,b}
->{(a,a)、(a,b)、(b,b)}
->{(a,a,a)、(a,a,b)、(a,b)、(b,a)、(b,a)、(b,a)、(b,a)、(b,b,b,b)}
func NAryProduct(输入字符串,n int)[]字符串{
例如,如果n满足您的限制
package main
import "fmt"
func nextPassword(n int, c string) func() string {
r := []rune(c)
p := make([]rune, n)
x := make([]int, len(p))
return func() string {
p := p[:len(x)]
for i, xi := range x {
p[i] = r[xi]
}
for i := len(x) - 1; i >= 0; i-- {
x[i]++
if x[i] < len(r) {
break
}
x[i] = 0
if i <= 0 {
x = x[0:0]
break
}
}
return string(p)
}
}
func main() {
np := nextPassword(2, "ABCDE")
for {
pwd := np()
if len(pwd) == 0 {
break
}
fmt.Println(pwd)
}
}
啊,我误解了“不是所有的记忆都同时存在”。我认为这意味着他不希望所有的1字符、2字符和3字符密码同时存储在内存中。并不是说他不希望所有的n字符密码都作为列表返回。你完全正确,闭包是正确的。太好了!这个算法基本上是在基len(c)中计算一个n
位数
据我所知。@NickCraig Wood:是的。该算法的一个关键元素是递增一个非负的n
-位,基len(c)
整数,溢出时有一个NaN异常。
func NAryProduct(input string, n int) []string {
if n <= 0 {
return nil
}
// Copy input into initial product set -- a set of
// one character sets
prod := make([]string, len(input))
for i, char := range input {
prod[i] = string(char)
}
for i := 1; i < n; i++ {
// The bigger product should be the size of the input times the size of
// the n-1 size product
next := make([]string, 0, len(input)*len(prod))
// Add each char to each word and add it to the new set
for _, word := range prod {
for _, char := range input {
next = append(next, word + string(char))
}
}
prod = next
}
return prod
}
package main
import "fmt"
func nextPassword(n int, c string) func() string {
r := []rune(c)
p := make([]rune, n)
x := make([]int, len(p))
return func() string {
p := p[:len(x)]
for i, xi := range x {
p[i] = r[xi]
}
for i := len(x) - 1; i >= 0; i-- {
x[i]++
if x[i] < len(r) {
break
}
x[i] = 0
if i <= 0 {
x = x[0:0]
break
}
}
return string(p)
}
}
func main() {
np := nextPassword(2, "ABCDE")
for {
pwd := np()
if len(pwd) == 0 {
break
}
fmt.Println(pwd)
}
}
AA
AB
AC
AD
AE
BA
BB
BC
BD
BE
CA
CB
CC
CD
CE
DA
DB
DC
DD
DE
EA
EB
EC
ED
EE