我制作了一个使用vigenere密码加密和解密邮件的程序。
在加密或解密文本时,会在其中打印一些额外的垃圾值。
它从名为input.txt
的文件输入并输出到output.txt
,您必须在input.txt
文件中写入消息,并且在运行时您必须提供密钥(a带字母数字字符的单词)。
为什么会这样?
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
int Encrypt(char key[]) // CODE FOR ENCRYPTION
{
int sz = 0, i;
FILE *ifp, *ofp;
ifp = fopen("input.txt", "r");
char *buffer;
char outputFilename[] = "output.txt";
if (ifp == NULL)
{
fprintf(stderr, "Cant open input file\n");
exit(1);
}
fseek(ifp, 0, SEEK_END);
sz = ftell(ifp);
// printf("%d",sz);
fseek(ifp, 0, SEEK_SET);
/* allocate memory for entire content */
buffer = (char *)malloc(sizeof(char) * sz);
if (!buffer)
fclose(ifp), fputs("memory alloc fails", stderr), exit(1);
/* copy the file into the buffer */
if (1 != fread(buffer, sz, 1, ifp))
fclose(ifp), free(buffer), fputs("entire read fails", stderr), exit(1);
ofp = fopen(outputFilename, "w");
if (ofp == NULL)
{
fprintf(stderr, "Can't open output file !\n");
}
// fprintf(ofp,"%s",buffer);
int j = 0;
for (i = 0; i < strlen(buffer); i++)
{
if (j > strlen(key) - 1)
j = 0;
if (buffer[i] >= 65 && buffer[i] < 91)
{
int c = ((((buffer[i] - 65) + ((key[j] - 65) % 26))) % 26) + 65;
fprintf(ofp, "%c", c);
}
else if (buffer[i] >= 97 && buffer[i] < 123)
{
int c = ((((buffer[i] - 97) + ((key[j] - 65) % 26))) % 26) + 97;
fprintf(ofp, "%c", toupper(c));
}
else
{
fprintf(ofp, "%c", buffer[i]);
continue;
}
j++;
}
printf("\n");
fclose(ifp);
fclose(ofp);
return 0;
}
int Decrypt(char key[]) // CODE FOR DECRYPTION
{
int sz = 0, i;
FILE *ifp, *ofp;
ifp = fopen("output.txt", "r");
char *buffer;
char outputFilename[] = "output2.txt";
if (ifp == NULL)
{
fprintf(stderr, "Cant open input file\n");
exit(1);
}
fseek(ifp, 0, SEEK_END);
sz = ftell(ifp);
// printf("%d",sz);
fseek(ifp, 0, SEEK_SET);
/* allocate memory for entire content */
buffer = (char *)malloc(sizeof(char) * sz);
if (!buffer)
fclose(ifp), fputs("memory alloc fails", stderr), exit(1);
/* copy the file into the buffer */
if (1 != fread(buffer, sz, 1, ifp))
fclose(ifp), free(buffer), fputs("entire read fails", stderr), exit(1);
ofp = fopen(outputFilename, "w");
if (ofp == NULL)
{
fprintf(stderr, "Can't open output file !\n");
}
// fprintf(ofp,"%s",buffer);
int j = 0;
for (i = 0; i < strlen(buffer); i++)
{
if (j > strlen(key) - 1)
j = 0;
if (buffer[i] >= 65 && buffer[i] < 91)
{
if (buffer[i] > key[j])
{
int c =
((((buffer[i] - 65) - ((key[j] - 65) % 26))) % 26) + 65;
fprintf(ofp, "%c", tolower(c));
}
else
{
int c = ((((buffer[i] - key[j]) + 26)) % 26) + 65;
fprintf(ofp, "%c", tolower(c));
}
}
else if (buffer[i] >= 97 && buffer[i] < 123)
{
int c = ((((buffer[i] - 97) - ((key[j] - 65) % 26))) % 26) + 97;
fprintf(ofp, "%c", tolower(c));
}
else
{
fprintf(ofp, "%c", buffer[i]);
continue;
}
j++;
}
printf("\n");
fclose(ifp);
fclose(ofp);
return 0;
}
void main()
{
int ch;
char key[20];
a:printf("0.Exit the Menu\n1.Encrypt\n2.Decrypt\n");
printf("Enter your choice\n");
scanf("%d", &ch);
switch (ch)
{
case 0:
printf("Goodbye\n");
break;
case 1:
printf
("-----------------------------Welcome to the encryption zone---------------------\n");
printf("Enter the key to be used\n");
scanf("%s", key);
Encrypt(key);
break;
case 2:
printf
("-----------------------------Welcome to the decryption zone---------------------\n");
printf("Enter the key to be used\n");
scanf("%s", key);
Decrypt(key);
break;
default:
printf("Enter the correct choice\n");
goto a;
break;
}
}
答案 0 :(得分:3)
在此分配和复制时
buffer = (char *)malloc(sizeof(char) * sz);
if (!buffer)
fclose(ifp), fputs("memory alloc fails", stderr), exit(1);
/* copy the file into the buffer */
if (1 != fread(buffer, sz, 1, ifp))
fclose(ifp), free(buffer), fputs("entire read fails", stderr), exit(1);
你在缓冲区中分配了sz
个字节,并复制了sz
个字节,但是你没有为空终结符留出空间。因此,当您检查strlen(buffer)
并稍后加密时,您将进入未分配的内存。
要解决此问题,您必须为'\0'
分配一个额外字节,或者复制少一个字节并在最后添加'\0'
。
答案 1 :(得分:0)
错误的长度计算。
正如@Dennis Meng所提到的,strlen(缓冲区)可能(* 1)超出了已分配缓冲区的末尾。你的malloc()
没问题。推荐的解决方案是不同的。而不是添加NUL字符,而是更改2 for
个循环
for (i = 0; i < strlen(buffer); i++)
到
for (i = 0; i < sz; i++)
这不仅会解决问题,而且会在您不再执行strlen(buffer)
sz
次时更快地运行。
* 1如果您的文件包含NUL字符,那就不会那么远了。如果确实超过buffer
的末尾,则停止的是UB。