douxi3404 2014-03-30 01:10
浏览 31

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

As part of a learning-Go exercise, I'm writing a simplistic brute-force password cracker.

To generate all possible 2-character passwords that use the characters A-E in Python, I would use itertools.product():

from itertools import product
for permutation in product('ABCDE', repeat=2):
  print permutation

However, I'm struggling to do this in Go.

Other questions seem to be about permutations, which isn't quite what I want. And while the Python docs include a sample implementation of the function, I don't know how to translate yield into Go.

I suppose I should mention two restrictions:

  1. I'd like the length of the password to be variable. That is, I may want to do 8-character passwords, or 6-character, or something else. This means we can't just nest n loops.
  2. I don't want to have all of them in memory at once.
  • 写回答

2条回答 默认 最新

  • doumanni3501 2014-03-30 02:47
    关注

    What you want is basically the n-ary cartesian product of a set with itself. So for all 3-character passwords you want Prod(set,set,set). This can be constructed iteratively. First construct the n-1 product, then for each product and each element of the initial set, add the element. So for instance all 2 character passwords -> 3 character passwords where the only valid characters are 'a' or 'b'.

    "ab" = {a,b} -> {(a,a),(a,b),(b,a),(b,b)} -> {(a,a,a),(a,a,b),(a,b,a),(a,b,b),(b,a,a),(b,a,b),(b,b,a),(b,b,b)}

    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
    }
    

    Playground version: http://play.golang.org/p/6LhApeJ1bv

    It should be noted that there's a lot of room for improvement on this solution. If you want to construct all passwords of length, say, 6-18, calling this method independently for each one will recalculate previously computed sets. I'll leave writing the better version up to you. Given what I've shown you, it shouldn't be too difficult to modify the code to take an arbitrary (n-m)ary product and compute the n-ary product from it. (Hint: think about how you'd do this recursively)

    评论

报告相同问题?

悬赏问题

  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)