字典生成算法实现(全排列实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package main
 
// @Title   main.go
// @Description 入口文件
// @Author  xiao
// @Update  none
 
import (
    "flag"
    "fmt"
    "log"
)
 
// 字典常量
const (
    lowerCaseChars = "abcdefghijklmnopqrstuvwxyz" // 小写字母
    upperCaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // 大写字母
    nums           = "0123456789"                 // 数字
    //nums           = "01"                               // 数字
    halfWidthChars = "`~!@#$%^&*()_+=-{}[]:\";’|<>?,./"  // 半角标点
    fullWidthChars = "`~!#¥%^&*()_+=-{}[]:";'\|<>?,./,。" // 全角标点
    //fullWidthChars = "`~"
    blankspace = " " // 空格
)
 
var wordLen int = 1
var lower bool
var upper bool
var num bool
var hf bool
var fl bool
var blank bool
 
// 默认情况下字典范围哦
var dicts string = ""
var runeDicts []rune
 
// @title   init
// @descroption  参数解析
// @auth    xiao 2023/01/13
// @update  none
// @param
// @return
func init() {
    flag.IntVar(&wordLen, "len", 1, "需要生成的单词长度")
    flag.BoolVar(&lower, "lower", false, "使用小写字母")
    flag.BoolVar(&upper, "upper", false, "使用大写字母")
    flag.BoolVar(&num, "num", false, "使用0-9数字")
    flag.BoolVar(&hf, "hf", false, "使用半角标点集合")
    flag.BoolVar(&fl, "fl", false, "使用全角表单集合")
    flag.BoolVar(&blank, "bl", false, "使用空格")
    flag.Parse()
}
 
func buildDicts() {
    if lower {
        dicts = dicts + lowerCaseChars
    }
 
    if upper {
        dicts = dicts + upperCaseChars
    }
 
    if num {
        dicts = dicts + nums
    }
 
    if hf {
        dicts = dicts + halfWidthChars
    }
 
    if fl {
        dicts = dicts + fullWidthChars
    }
 
    if blank {
        dicts = dicts + blankspace
    }
 
    if wordLen <= 0 {
        log.Fatal("参数设置错误!")
    }
 
    if len(dicts) == 0 {
        log.Fatal("所选字典为空!")
    }
 
    runeDicts = []rune(dicts)
}
 
// wheel
type wheel struct {
    charIndex int
    prewheel  *wheel
    lastwheel bool
}
 
// @title   gen
// @descroption  遍历生成本齿轮中的字符序列
// @auth    xiao 2023/01/14
// @update  none
// @param word *string 字典结果
// @return 字典结果
func (cg *wheel) gen(word *string) (*string, bool) {
    if cg.charIndex == len(runeDicts) {
        cg.charIndex = 0
        cg.notifyPreWheel()
        return word, true
    }
    if cg.charIndex < len(runeDicts) {
        *word = string(runeDicts[cg.charIndex]) + *word
        if cg.lastwheel {
            cg.charIndex++
        }
    }
    return word, false
}
 
// @title   notifyPreWheel
// @descroption  通知齿轮中前一个齿轮滑动到下一个字符序列
// @auth    xiao 2023/01/14
// @update  none
// @param
// @return void
func (w *wheel) notifyPreWheel() {
    if w.prewheel != nil {
        w.prewheel.charIndex++
    }
}
 
var wheels = make([]*wheel, 0)
 
func buildDictWheels() {
    for i := 0; i < wordLen; i++ {
        if i == 0 {
            wheels = append(wheels, &wheel{prewheel: nil, charIndex: 0, lastwheel: false})
        } else {
            w := wheels[i-1]
            wheels = append(wheels, &wheel{prewheel: w, charIndex: 0, lastwheel: false})
        }
    }
    wheels[len(wheels)-1].lastwheel = true
}
 
// @title   main
// @descroption  main
// @auth    xiao 2023/01/13
// @update  none
// @param
// @return  0 执行成功 1 执行异常
func main() {
    buildDicts()
    log.Println("当前所选字符集合:", dicts)
 
    buildDictWheels()
 
    for {
        stopflag := true
        skipWord := false
        word := ""
        for i := len(wheels) - 1; i >= 0; i-- {
            _, stop := wheels[i].gen(&word)
            if stop {
                skipWord = true
            }
            stopflag = stop && stopflag
        }
        if stopflag {
            break
        }
        if !skipWord {
            fmt.Println(word)
        }
    }
}

没什么好说的,直接贴代码吧,见过水表么?水表里面就是N多个齿轮组合在一起,最后一个齿轮转一圈带动前面一个齿轮转一下,当所有齿轮转到最大的时候表示所有字符组合遍历完一遍。代码实现每一位密码相当于一个水表齿轮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#./dictgen -len 2 -num -lower > 1.txt
#cat 1.txt
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
an
ao
ap
aq
ar
as
at
au
av
aw
ax
ay
az
a0
a1
a2
a3
a4
a5
a6
...

为什么不用递归来生成密码?8位以上大小写字符数字密码递归估计没什么机器能搞下来吧!但这土鳖办法却能!

posted @   一朵野生菌  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示