将加密字符串与 strcmp 进行比较
Compare encrypted strings with strcmp
我正在努力填补我在计算机科学自学方面的空白,并在 Edx 上学习 CS50 课程。我对C完全陌生。在其中一个问题集中,我必须比较用crypt函数加密的字符串。
在下面的示例中,我无法理解为什么 strcmp
returns 0(即 'claims' 字符串相等:
#include <crypt.h>
#include <stdio.h>
#include <string.h>
#define _XOPEN_SOURCE
int main(void)
{
char string1[4] = "foo[=10=]";
char string2[4] = "bar[=10=]";
printf("crypt1: %s\n",crypt(string1, "50[=10=]"));
printf("crypt2: %s\n",crypt(string2, "50[=10=]"));
if (strcmp(crypt(string1, "50[=10=]"),crypt(string2, "50[=10=]")) == 0)
{
printf("crypt1: %s\n",crypt(string1, "50[=10=]"));
printf("crypt2: %s\n",crypt(string2, "50[=10=]"));
return 0;
}
}
当我运行程序时,输出值为:
crypt1: 50GbL/FUeE/J6
crypt2: 50hmnpE.bRNiU
crypt1: 50GbL/FUeE/J6
crypt2: 50hmnpE.bRNiU
if
条件中的代码怎么可能被执行?
如 Martin 的评论中所述,crypt returns 指向静态缓冲区的指针,该缓冲区在每次调用时都会被覆盖。所以 strcmp 实际上被传递给同一个缓冲区 - crypt 的第一个值已经被第二个覆盖 - 一旦两个参数被评估。
与以下内容相关:
[并且,就其价值而言,在 C 中,任何 returns 字符串 (char *) 的函数都必须从某处获取该字符串的内存。您要么需要将缓冲区作为参数传入,要么需要它自己找到它。而且因为 C 不进行垃圾收集并且需要手动内存管理(例如 malloc/free),所以不将结果缓冲区作为参数的函数应该抛出一个红旗 - 结果是静态缓冲区(即像这样被覆盖)?完成后是否需要释放它?否则,您可能会遇到内存泄漏或错误的风险。)
显然,crypt()
在每次调用时为加密字符串使用相同的缓冲区:
char string1[] = "foo";
char string2[] = "bar";
char *crypt1 = crypt(string1, "50");
printf("crypt1: %s\n", crypt1); // crypt1: 50GbL/FUeE/J6
char *crypt2 = crypt(string2, "50");
printf("crypt1: %s\n", crypt1); // crypt1: 50hmnpE.bRNiU
printf("crypt2: %s\n", crypt2); // crypt2: 50hmnpE.bRNiU
为了保留(并比较)两个结果,您必须 strdup()
它们或将它们复制到一个单独的数组中。
我正在努力填补我在计算机科学自学方面的空白,并在 Edx 上学习 CS50 课程。我对C完全陌生。在其中一个问题集中,我必须比较用crypt函数加密的字符串。
在下面的示例中,我无法理解为什么 strcmp
returns 0(即 'claims' 字符串相等:
#include <crypt.h>
#include <stdio.h>
#include <string.h>
#define _XOPEN_SOURCE
int main(void)
{
char string1[4] = "foo[=10=]";
char string2[4] = "bar[=10=]";
printf("crypt1: %s\n",crypt(string1, "50[=10=]"));
printf("crypt2: %s\n",crypt(string2, "50[=10=]"));
if (strcmp(crypt(string1, "50[=10=]"),crypt(string2, "50[=10=]")) == 0)
{
printf("crypt1: %s\n",crypt(string1, "50[=10=]"));
printf("crypt2: %s\n",crypt(string2, "50[=10=]"));
return 0;
}
}
当我运行程序时,输出值为:
crypt1: 50GbL/FUeE/J6
crypt2: 50hmnpE.bRNiU
crypt1: 50GbL/FUeE/J6
crypt2: 50hmnpE.bRNiU
if
条件中的代码怎么可能被执行?
如 Martin 的评论中所述,crypt returns 指向静态缓冲区的指针,该缓冲区在每次调用时都会被覆盖。所以 strcmp 实际上被传递给同一个缓冲区 - crypt 的第一个值已经被第二个覆盖 - 一旦两个参数被评估。
与以下内容相关:
[并且,就其价值而言,在 C 中,任何 returns 字符串 (char *) 的函数都必须从某处获取该字符串的内存。您要么需要将缓冲区作为参数传入,要么需要它自己找到它。而且因为 C 不进行垃圾收集并且需要手动内存管理(例如 malloc/free),所以不将结果缓冲区作为参数的函数应该抛出一个红旗 - 结果是静态缓冲区(即像这样被覆盖)?完成后是否需要释放它?否则,您可能会遇到内存泄漏或错误的风险。)
显然,crypt()
在每次调用时为加密字符串使用相同的缓冲区:
char string1[] = "foo";
char string2[] = "bar";
char *crypt1 = crypt(string1, "50");
printf("crypt1: %s\n", crypt1); // crypt1: 50GbL/FUeE/J6
char *crypt2 = crypt(string2, "50");
printf("crypt1: %s\n", crypt1); // crypt1: 50hmnpE.bRNiU
printf("crypt2: %s\n", crypt2); // crypt2: 50hmnpE.bRNiU
为了保留(并比较)两个结果,您必须 strdup()
它们或将它们复制到一个单独的数组中。