密码字典生成代码生成空TXT文件问题求助
问题分析与修复方案
核心问题
1. 整数溢出与pow函数的精度问题
你的代码中num_combinations = pow(charset_length, max)存在两个致命问题:
pow返回double类型,当charset_length=62、max=8时,计算结果为218340105584896,远超过32位int的最大值(2147483647),赋值给int变量会直接溢出,导致num_combinations变成负数或无效值,循环条件i < num_combinations不成立,循环完全不执行,因此文件为空。- 即使是较小的
max值,pow的浮点精度也可能导致计算结果偏差,比如某些大数无法被double精确表示,最终得到错误的组合数。
2. 密码生成逻辑错误
- 初始
length = min,但生成短于charset_length^min的数字时,index = i小于charset_length,while循环不执行,此时仅password[length-1]被赋值,前面的字符位都是未初始化的垃圾值,生成的密码无效。 - 试图用单个循环覆盖所有长度的组合,逻辑上不成立,应该针对每个长度(从
min到max)单独生成所有可能的组合。
3. 未初始化内存
分配的password内存未初始化,未赋值的位置会包含垃圾数据,写入文件的内容会有乱码。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 计算 charset_length^n,用unsigned long long避免溢出 unsigned long long power(int base, int exp) { unsigned long long result = 1; for (int i = 0; i < exp; i++) { result *= base; } return result; } void Dictionary_Generator(char *charset, int min, int max) { int charset_length = strlen(charset); // 分配内存并初始化为0,避免垃圾值 char *password = calloc(max + 1, sizeof(char)); if (password == NULL) { fprintf(stderr, "Error: memory allocation failed\n"); exit(1); } FILE *file = fopen("dictionary.txt", "w"); if (file == NULL) { fprintf(stderr, "Error: could not create file\n"); free(password); exit(1); } // 遍历每个长度:从min到max for (int len = min; len <= max; len++) { unsigned long long total = power(charset_length, len); // 生成当前长度的所有组合 for (unsigned long long i = 0; i < total; i++) { unsigned long long index = i; // 从后往前填充字符,生成len位的密码 for (int pos = len - 1; pos >= 0; pos--) { password[pos] = charset[index % charset_length]; index /= charset_length; } password[len] = '\0'; // 写入文件 int result = fprintf(file, "%s\n", password); if (result < 0) { perror("Error writing to file"); fclose(file); free(password); exit(1); } } } fclose(file); free(password); } int main() { char *charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; int min = 4; int max = 8; Dictionary_Generator(charset, min, max); return 0; }
修复要点说明
- 用自定义的
power函数代替pow,使用unsigned long long类型存储组合数,彻底避免整数溢出和浮点精度问题。 - 分长度循环生成密码,每个长度单独处理,逻辑清晰且正确。
- 用
calloc分配内存并自动初始化为0,避免垃圾值干扰。 - 从后往前填充密码字符,确保每个位置都被正确赋值,生成有效的固定长度密码。
内容的提问来源于stack exchange,提问作者Gabriel Garcia
相关产品推荐
相关产品推荐

