我在使用以下格式打印十六进制时遇到了一些内存问题:\ xAA \ xAB \ xDC使用我的加密例程。
我做了一些修改,使用snprintf()
和strcat()
来尝试修复输出,并且它在某种程度上有效。
这是我最初开始使用的功能,可能比我的修改版本更好。
char *encrypt(char key, const char *a) {
char *output = malloc(strlen(a)+1);
bzero(output, strlen(a)+1);
strcpy(output, a);
char *tmp = output;
int i;
for (i = 0; tmp[i] != 0; i++) {
tmp[i] = key ^ tmp[i];
}
return output;
}
我目前的进展如下:
char *encrypt(char key, const char *a)
{
char buf[256];
char *tmp = a;
int i;
int *k;
for (i = 0; tmp[i] != 0; i++)
{
char temp[10];
k = key ^ tmp[i];
snprintf(temp, sizeof(temp), "\\x%s", k);
strcat(buf, temp);
}
return buf;
}
int main(int argc, char **argv)
{
if (argv[1] == NULL){
printf("Usage: %s <string>\n", argv[0]);
}
else printf("Encrypted string: %s\n", encrypt(0xEB, argv[1]));
return 0;
}
如果有人能指出我如何解决内存问题的正确方向,如果代码可以改进,我会非常感激。
答案 0 :(得分:3)
代码中的主要问题buf
是函数encrypt()
的本地问题。所以你可能不会从函数返回数组。函数完成后,数组将不再存在,返回的地址将无效。如果返回的值在调用者中使用,则它将调用undefined behavior。
您需要将buf
定义为指针,并使用malloc()
或系列分配动态内存。此外,一旦使用结束,您需要free()
内存。
那就是说,
k
定义为指针但未向其分配内存。k = key ^ tmp[i];
似乎没有意义,也许你的意思是*k = key ^ tmp[i];
%s
期望指向char
数组(以null结尾)作为参数。从那时起,snprintf(temp, sizeof(temp), "\\x%s", k);
看起来也是错误的。您需要snprintf(temp, sizeof(temp), "\\x%d", *k);
来打印int
值。答案 1 :(得分:0)
而不是:
int *k;
k = key ^ tmp[i];
snprintf(temp, sizeof(temp), "\\x%s", k);
使用它:
unsigned char k;
k = key ^ tmp[i];
snprintf(temp, sizeof temp, "\\x%02X", k);
请注意,您还需要对buf
进行其他更改。首先你永远不会初始化它,所以你附加垃圾。你永远不会检查你是否没有溢出它。
此外,您尝试从函数返回此函数,但由于它是局部变量,因此在函数返回时它将不再存在。
有关如何从函数中获取新写入字符串的一些建议,请参阅this thread。您可以使用malloc(256)
与第一次尝试相同(并记住在sizeof buf
调用中使用mallocated长度替换snprintf
。
对密钥和邮件使用unsigned char
而不是char
会更加健壮。问题的一个示例是,在x86或x64上,char
的范围为-128
到127
,因此当您提供0xEB
(即235
)时是一个超出范围的任务,没有明确定义。
但是在常见系统上,您将使用char
,因为它们倾向于通过使用2的补码和截断多余的位来定义超出范围的赋值,这在您的情况下有效。