You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

指针与字符串问题:Diceware密码生成器输出乱码求助

Diceware密码短语生成器乱码问题修复

核心错误分析

  • 字符串赋值错误:*word = wordline; 是把指针的内存地址赋值给单个char变量,完全不是字符串复制操作,这是乱码的直接原因。
  • 匹配逻辑错误:原代码用strstr(line, combo)判断匹配,只要行中包含目标数字串就会触发,但词表中目标数字是行首固定的5位,这种判断会误匹配单词中包含相同数字序列的行。
  • 未终止循环:找到匹配行后未跳出循环,会继续读取后续行,可能覆盖正确结果。
  • 缺少成功返回值:get_word函数成功执行后未返回0,会导致main函数误判操作失败。
  • 冗余指针声明:char *ptr = &word1; 完全多余,数组名本身就是指向首元素的指针,直接传递word1即可。

修复后的完整代码

#include <stdio.h>
#include <string.h>
#include <sodium.h>

void roll_dice(char *combo) {
    uint32_t dice1, dice2, dice3, dice4, dice5;
    uint32_t upper = 6;

    dice1 = randombytes_uniform(upper) + 1;
    dice2 = randombytes_uniform(upper) + 1;
    dice3 = randombytes_uniform(upper) + 1;
    dice4 = randombytes_uniform(upper) + 1;
    dice5 = randombytes_uniform(upper) + 1;

    sprintf(combo, "%d%d%d%d%d", dice1, dice2, dice3, dice4, dice5);
}

int get_word(char *combo, char *word) {
    FILE *stream;
    char line[20];
    char *tab_pos;

    stream = fopen("/usr/local/etc/passwiz/eff_large_wordlist.txt", "r");
    if (NULL == stream) {
        printf("Failed to open wordlist\n");
        return -1;
    }

    while (fgets(line, sizeof(line), stream)) {
        // 精确匹配行首的5位数字
        if (strncmp(line, combo, 5) == 0) {
            // 定位制表符,提取后续单词
            tab_pos = strchr(line, '\t');
            if (tab_pos != NULL) {
                // 去除行尾换行符并复制单词到目标缓冲区
                strtok(tab_pos + 1, "\n");
                strcpy(word, tab_pos + 1);
                fclose(stream);
                return 0; // 找到结果后立即终止循环并返回
            }
        }
    }

    // 未找到匹配单词的情况
    printf("No matching word found for combo: %s\n", combo);
    fclose(stream);
    return -1;
}

int main(void) {
    if (sodium_init() < 0) {
        return 1;
    }

    char combo[6];
    roll_dice(combo);
    printf("Dice numbers: %s\n", combo);

    char word1[20];
    if (get_word(combo, word1) < 0) {
        return 1;
    }

    printf("First word: %s\n", word1);

    // TODO: 获取6个单词
    return 0;
}

关键修复说明

  1. 正确的字符串复制:用strcpy(word, tab_pos + 1)替代错误的指针赋值,将提取到的单词复制到传入的缓冲区中。
  2. 精准匹配逻辑:使用strncmp(line, combo, 5)确保只匹配行首的5位数字,避免误匹配。
  3. 高效终止流程:找到匹配行后立即关闭文件并返回,避免无效的后续读取操作。
  4. 完善的单词提取:通过strchr定位制表符,跳过分隔符后提取单词,并用strtok去除行尾的换行符,保证输出格式正确。
  5. 简化指针传递:移除冗余的指针声明,直接传递数组名,符合C语言的数组使用规范。

内容的提问来源于stack exchange,提问作者Douglas Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:21:11