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

c - printf("%s") prints an additional @

我对 cs50 编程教程的研究是正确的。这里我应该破解一个DES加密的字符串。

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

在下一步中,我将其放入两个 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
        }
    }
}

你没有发布任何代码,但我猜你没有空终止你传递给 printf()...

的数组

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

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

  • 你可以把数组加长,在字符后面设置一个'[=18=]'

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

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

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

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

的第一个字节中

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