c# 代码生成文本文件,但文件为空

0vvn1miw  于 2023-03-06  发布在  C#
关注(0)|答案(2)|浏览(400)

我编写了一个代码,用于编写密码字典,但它不写入. txt文件
代码生成一个文本文件,然后使用我定义的字符集写入所有可能的密码,但它不写入文本文件。
这是密码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void Dictionary_Generator(char *charset, int min, int max) {
    char *password = malloc((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");
        exit(1);
    }

    int charset_length = strlen(charset);
    int num_combinations = pow(charset_length, max);

    for (int i = 0; i < num_combinations; i++) {
        int index = i;
        int length = min;
        while (index >= charset_length) {
            password[length - 1] = charset[index % charset_length];
            index /= charset_length;
            length++;
        }
        password[length - 1] = charset[index];
        password[length] = '\0';
        if (length >= min) {
            int result = fprintf(file, "%s\n", password);
            if (result < 0) {
                perror("Error writing to file");
                exit(1);
    }
        }
    }

    fclose(file);
    free(password);
}

int main() {
    char *charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    int min = 4;
    int max = 8;
    Dictionary_Generator(charset, min, max);
    return 0;
}

它生成一个文本文件,但该文件为空。

pinkon5k

pinkon5k1#

通过在cc行的末尾添加-lm来修复undefined reference to 'pow'后,出现另一个错误:
charset_length是62。max是8。
因此,当您这样做时:

int num_combinations = pow(charset_length, max);

我们正在执行pow(62,8),当截断为int时,得到一个负数,pow的结果大约为2.1e14,对于int来说太大了。
因此,后续的for循环将执行 * 零 * 次。
您可能希望使用long long来代替,但是2e14迭代似乎很多。
执行:

int num_combinations = pow(charset_length, max - min);

看起来更合理(并且 * 适合 * int)。但是,在这种情况下,程序只输出空行。

    • 更新**

当我进行类似类型的迭代时,我使用了一个长度为当前数字宽度的"辅助"向量,我将其视为一个N位宽度的数字(charset_length)。
它接受0到charset_length-1范围内的每个数字的值。
我认为更简单的方法是让外部循环输出字长(例如4 - 8),然后从charset生成该长度的所有字
因此,我不得不做一些相当大的重构,将生成代码分成多个函数。
实际的运行时非常大,所以我将进度输出添加到stdout ...
下面是重构后的代码,它带有注解:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>

// incbignum -- increment the base N number
// RETURNS: carryout/overflow
int
incbignum(unsigned char *bignum,int iwid,int base)
{
    int carry = 1;

    for (int idx = 0;  idx < iwid;  ++idx) {
        int val = bignum[idx];
        val += carry;

        carry = (val >= base);
        if (carry)
            val %= base;

        bignum[idx] = val;

        if (! carry)
            break;
    }

    return carry;
}

// tscgetf -- get time in fractional seconds
double
tscgetf(void)
{
    struct timespec ts;
    double sec;

    clock_gettime(CLOCK_MONOTONIC,&ts);

    sec = ts.tv_nsec;
    sec /= 1e9;
    sec += ts.tv_sec;

    return sec;
}

// genlength -- generate all words of a given length from all chars in charset
void
genlength(FILE *file,const char *charset,int iwid)
{
    int charset_length = strlen(charset);
    unsigned long long wordcount = 0;

    char buffer[iwid + 1];

    // create a number in base(charset_length) with iwid number of digits
    unsigned char bignum[iwid];
    memset(bignum,0,iwid);

    // show some progress
    printf("genlength: iwid=%d\n",iwid);

    double tscold = tscgetf();

    while (1) {
        // get the current output word
        for (int idx = 0;  idx < iwid;  ++idx)
            buffer[idx] = charset[bignum[idx]];
        buffer[iwid] = 0;

        // send it to the file
        fputs(buffer,file);
        fputc('\n',file);

        // advance the base(charset_length) number
        if (incbignum(bignum,iwid,charset_length))
            break;

        // show progress
        if ((++wordcount % 3761) == 0) {
            double tscnow = tscgetf();
            if ((tscnow - tscold) >= 1.0) {
                printf("\rwordcount=%llu %s",wordcount,buffer);
                fflush(stdout);
                tscold = tscnow;
            }
        }
    }

    printf("\nfinal=%llu\n",wordcount);
}

void
Dictionary_Generator(const char *charset, int min, int max)
{
    char *password = malloc((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");
        exit(1);
    }

    int charset_length = strlen(charset);
#if 0
    int num_combinations = pow(charset_length, max);
#else
    int num_combinations = pow(charset_length, max - min);
#endif
    printf("num_combinations=%d\n",num_combinations);

#if 0
    for (int i = 0; i < num_combinations; i++) {
        int index = i;
        int length = min;

        while (index >= charset_length) {
            password[length - 1] = charset[index % charset_length];
            index /= charset_length;
            length++;
        }
        password[length - 1] = charset[index];
        password[length] = '\0';
        if (length >= min) {
            int result = fprintf(file, "%s\n", password);

            if (result < 0) {
                perror("Error writing to file");
                exit(1);
            }
        }
    }
#else
    for (int iwid = min;  iwid <= max;  ++iwid)
        genlength(file,charset,iwid);
#endif

    fclose(file);
    free(password);
}

int
main()
{
// NOTE -- the full charset takes a _long_ time ... :-)
#if TEST
    const char *charset = "abcdefghijklmnopqrstuvwxyz";
#else
    const char *charset = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789";
#endif
    int min = 4;
    int max = 8;

    Dictionary_Generator(charset, min, max);

    return 0;
}
mspsb9vt

mspsb9vt2#

这段代码似乎将应该写入文件的字符串赋给了一个变量,但实际上并没有将其写入文件。

if (length >= min) {
        int result = fprintf(file, "%s\n", password);
        if (result < 0) {
            perror("Error writing to file");
            exit(1);
}

相关问题