Go 生成所有可能的n字符密码

Go 生成所有可能的n字符密码,go,Go,作为学习围棋练习的一部分,我正在编写一个简单的蛮力密码破解程序 要生成所有可能使用Python中A-E字符的2字符密码,我将使用: 然而,在围棋中我很难做到这一点 似乎是关于排列,这不是我想要的。虽然Python文档包含函数的示例实现,但我不知道如何将yield转换为Go 我想我应该提到两个限制: 我希望密码的长度是可变的。也就是说,我可能想要8个字符的密码,或者6个字符的密码,或者其他什么。这意味着我们不能只嵌套n个循环 我不想一下子把它们都记起来 你想要的基本上是一个集合本身。因此,对于所有

作为学习围棋练习的一部分,我正在编写一个简单的蛮力密码破解程序

要生成所有可能使用Python中A-E字符的2字符密码,我将使用:

然而,在围棋中我很难做到这一点

似乎是关于排列,这不是我想要的。虽然Python文档包含函数的示例实现,但我不知道如何将
yield
转换为Go

我想我应该提到两个限制:

  • 我希望密码的长度是可变的。也就是说,我可能想要8个字符的密码,或者6个字符的密码,或者其他什么。这意味着我们不能只嵌套n个循环
  • 我不想一下子把它们都记起来

  • 你想要的基本上是一个集合本身。因此,对于所有需要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