求助:实现基于记忆密码的字典生成程序(递归写入文件)
解决递归生成密码字典的问题
你的思路完全没问题,现在就差把递归生成组合的核心逻辑补全,我来帮你完善代码并解释清楚:
现有代码的问题点
Append方法里的换行符写错了:\\r \\n会被解析成字面量的\r \n(中间多了空格),应该用\r\n或者更通用的Environment.NewLine。Calc方法的递归逻辑未完成,没有处理到最后一个字符时的写入操作,也没有正确递归到下一个字符位置。- 缺少对空输入/空路径的判断,容易导致程序崩溃。
完整修正后的代码
using System; using System.Collections.Generic; using System.IO; namespace strGen { class Program { static List<char[]> ls { get; set; } static string Path { get; set; } static string input { get; set; } static char[] inputChars { get; set; } static void Main(string[] args) { Console.Write("Enter tip: "); input = Console.ReadLine(); // 空输入判断,避免后续报错 if (string.IsNullOrEmpty(input)) { Console.WriteLine("Input cannot be empty!"); return; } Console.Write("Enter path: "); Path = Console.ReadLine(); // 路径合法性简单判断 if (string.IsNullOrEmpty(Path)) { Console.WriteLine("Path cannot be empty!"); return; } inputChars = input.ToCharArray(); MakeList(inputChars); // 启动递归生成,初始字符串为空,从第0个字符位置开始 Calc("", 0); Console.WriteLine("Password dictionary generated successfully!"); } /// <summary> /// Makes list of all possible characters, for every character in a character array /// </summary> /// <param name="inputChars"></param> static void MakeList(char[] inputChars) { ls = new List<char[]>(); foreach (char c in inputChars) { char cU; char cL; char[] tmp; if (char.IsLetter(c)) { if (c == 'a' || c == 'A') { tmp = new char[3]; cL = char.ToLower(c); cU = char.ToUpper(c); tmp[0] = cL; tmp[1] = cU; tmp[2] = '@'; } else if (c == 's' || c == 'S') { tmp = new char[3]; cL = char.ToLower(c); cU = char.ToUpper(c); tmp[0] = cL; tmp[1] = cU; tmp[2] = '5'; } else { tmp = new char[2]; cL = char.ToLower(c); cU = char.ToUpper(c); tmp[0] = cL; tmp[1] = cU; } } else if (char.IsDigit(c)) { if (c == '1') { tmp = new char[2]; tmp[0] = c; tmp[1] = '!'; } else { tmp = new char[1]; tmp[0] = c; } } else if (c == '!') { tmp = new char[2]; tmp[0] = c; tmp[1] = '1'; } else { tmp = new char[1]; tmp[0] = c; } ls.Add(tmp); } } static void Append(string str) { // 使用Environment.NewLine适配不同系统的换行符 File.AppendAllText(Path, str + Environment.NewLine); } static void Calc(string currentStr, int index) { // 递归终止条件:当index等于字符数组列表的长度时,说明已经生成了一个完整的密码 if (index == ls.Count) { Append(currentStr); return; } // 遍历当前位置的所有可选字符 foreach (char c in ls[index]) { // 把当前字符加到现有字符串后面,递归处理下一个位置 Calc(currentStr + c, index + 1); } } } }
代码逻辑解释
递归核心逻辑:
Calc方法是生成所有密码组合的关键:- 当
index等于ls.Count时,意味着已经处理完所有字符位置,生成了一个完整的密码,调用Append写入文件。 - 否则,遍历当前位置对应的所有可选字符,将每个字符追加到
currentStr后,递归调用Calc处理下一个字符位置,以此遍历所有可能的组合。
- 当
细节优化:
- 增加了输入和路径的空值判断,避免程序崩溃。
- 简化了字母大小写转换的代码,不需要重复判断原字符的大小写。
- 使用
Environment.NewLine替代硬编码的换行符,让生成的文件在Windows/Linux系统下都能正常换行。
后续使用建议
生成字典文件后,你可以用Hydra进行暴力破解,示例命令(根据路由器登录页面调整):
# GET请求登录示例 hydra -L 生成的密码字典路径 -p '' http-get://你的路由器IP/login
如果路由器是POST登录,需要调整为http-post-form并指定登录参数,比如:
hydra -L pass.txt -p '' 路由器IP http-post-form "/login.php:username=admin&password=^PASS^:Invalid password"
内容的提问来源于stack exchange,提问作者AsPas
相关产品推荐
相关产品推荐

