c - printf ("%s") 打印一个额外的 @

标签 c printf cs50

我很清楚正在编写 cs50 编程教程。这里我应该破解一个 DES 加密的字符串。

首先,我专注于创建一个 64 位大数组,其中包含盐中使用的所有可能的字符。

在下一步中,我将其放入两个 for 循环中,以打印出这两个 for 循环的所有可能组合。这就是我现在所处的位置。

出于调试原因,我只是使用 printf("%s",salt) 将其打印出来。盐定义为 char salt[2]。但由于某种原因,它总是打印出xx@(xx每次都会按预期变化,我不知道@来自哪里)。

首先,我认为它可能会由于某种奇怪的原因超出数组并从随机内存中获取@。这就是为什么我将它从在线 IDE 复制到本地 XCode 中。仍然是相同的 @ 符号。现在我对 @ 的来源感到困惑。

Link to my code.

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define _XOPEN_SOURCE       // DES - implementation
#include <unistd.h>

// shorthands
#define cypher argv[1]

#define ascii_dot 46
#define ascii_slash 47
#define ascii_zero 48
#define ascii_nine 57
#define salt_size 64

#define majA 65
#define majZ 90

#define minA 97
#define minZ 122

int main(int argc, string argv[]) {
    // Checking input
    if (argc != 2) {
        printf("<usage>\n<./crack <password_hash>");
        return 1;
    }

    // Create a salter
    // 2 * 26 for letters + 10 for numbers + dot and slash = 64 = salt_size
    char salt_crystal[salt_size];

    {   // Own scope to not waste space for salt_iterator
        int salt_iterator = 0; // used to create salt crystals

        //minuscels
        for (int i = minA; i <= minZ; i++)
            salt_crystal[salt_iterator++] = (char)i;
        //majuscels
        for (int i = majA; i <= majZ; i++)
            salt_crystal[salt_iterator++] = (char)i;
        //ascii_dot to 9
        for (int i = ascii_dot; i <= ascii_nine; i++)
            salt_crystal[salt_iterator++] = (char) i;
    }

    // make the salt and forward it to the next function 
    for (int i = 0, l = salt_size; i < l; i++) {
        char salt[2];
        salt[0] = salt_crystal[i];
        for (int i2 = 0, l2 = salt_size; i2 < l2; i2++) {
            salt[1] = salt_crystal[i2];
            printf("%s ", salt); // DEBUG
        }
    }
}

最佳答案

您还没有发布任何代码,但我猜您没有以 null 终止传递给 printf() 的数组...

编辑 猜测不错:您将 2 个字符设置为 char salt[2] 并将其传递给 printfprintf 打印这些内容,并继续从内存中读取超出 salt 数组末尾的字符,直到找到结束该数组的 '\0' 字节。字符串。

有不同的方法可以解决这个问题:

  • 您可以使数组更长,并在字符后面设置 '\0':

    char salt[3];
    ...
    salt[2] = '\0';
    printf("%s", salt);
    
  • 您可以在 printf 格式中使用精度值 2 来打印数组中最多 2 字节:

    printf("%.2s", salt);
    
  • 您可以打印数组中的各个字节:

    putchar(salt[0]);
    putchar(salt[1]);
    

至于为什么你总是得到@,没有明确的答案,因为你正在经历未定义的行为,所以任何事情都可能发生......但请注意,@有value 64 这是您存储到局部变量l 中的值。 salt 数组可能位于内存中 l 变量之前。在小端字节序中,值 64 存储在 l 的第一个字节中。

另请注意,不建议将名称 l 用于变量,因为很难与固定字体中的数字 1 区分开来。

关于c - printf ("%s") 打印一个额外的 @,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39578071/

相关文章:

c - 如何索引 "struct"成员?如何在 C 中正确访问它们?

c - 使用其内核命名空间 PID 从全局范围内终止进程

C 程序跳过字符串中的第一个字符

c - 确定参数列表中参数类型的简单方法

c - 这个小的 printf 循环似乎不知从哪里发出了一个额外的字节,为什么?

CS50 Mario(更舒适)错误消息

c - 在C中,我应该如何读取文本文件并打印所有字符串

c - 如果在文件上运行相同的程序,lockf 不起作用

c - 在 c 中重新分配的正确方法

c - printf 不打印变量