我一直在尝试使用一个非常简单的加密程序,它应该像这样工作:
- 生成ASCII字符的随机密钥(只是ascii表的排列)
- 对于要加密的文件中的每个字符,获取其十进制表示(X),然后将其替换为键处索引X处的字符。
问题是它破坏了一些文件,我不知道为什么。
任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main()
{
int temp,used[256];
char *key,*mFile;
long i,fSize;
memset(used,0,sizeof(used));
srand(time(NULL));
FILE *pInput = fopen("Input.in","rb");
FILE *pOutput = fopen("Encrypted.out","wb");
FILE *pKeyOutput = fopen("Key.bin","wb");
if(pInput==NULL||pOutput==NULL||pKeyOutput==NULL)
{
printf("File I/O Error\n");
return 1;
}
key = (char*)malloc(255);
for(i=0;i<256;i++)
{
temp = rand()%256;
while(used[temp])
temp = rand()%256;
key[i] = temp;
used[temp] = 1;
}
fwrite(key,1,255,pKeyOutput);
fseek(pInput,0,SEEK_END);
fSize = ftell(pInput);
rewind(pInput);
mFile = (char*)malloc(fSize);
fread(mFile,1,fSize,pInput);
for(i=0;i<fSize;i++)
{
temp = mFile[i];
fputc(key[temp],pOutput);
}
fclose(pInput);
fclose(pOutput);
fclose(pKeyOutput);
free(mFile);
free(key);
return 0;
}
解密例程:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int temp,j;
char *key,*mFile;
long i,fSize;
FILE *pKeyInput = fopen("key.bin","rb");
FILE *pInput = fopen("Encrypted.out","rb");
FILE *pOutput = fopen("Decrypted.out","wb");
if(pInput==NULL||pOutput==NULL||pKeyInput==NULL)
{
printf("File I/O Error\n");
return 1;
}
key = (char*)malloc(255);
fread(key,1,255,pKeyInput);
fseek(pInput,0,SEEK_END);
fSize = ftell(pInput);
rewind(pInput);
mFile = (char*)malloc(fSize);
fread(mFile,1,fSize,pInput);
for(i=0;i<fSize;i++)
{
temp = mFile[i];
for(j=0;j<256;j++)
{
if(key[j]==temp)
fputc(j,pOutput);
}
}
fclose(pInput);
fclose(pOutput);
fclose(pKeyInput);
free(mFile);
free(key);
return 0;
}
答案 0 :(得分:2)
确保使用unsigned char
;如果char
已签名,则处理0x80..0xFF范围内的字符时会出错。具体来说,您将在“映射表”中访问负索引。
当然,严格来说,ASCII是一个7位代码集,0x00..0x7F范围之外的任何字符都不是ASCII。
您只需分配255个字节,然后继续覆盖超出分配的一个字节。这是一个基本的缓冲区溢出;你调用未定义的行为(这意味着任何可能发生的事情,包括它可能在没有造成麻烦的情况下正常工作 - 在某些机器上)。
另一个问题是你为256个可能的字节码中的255个写了映射,这令人费解。其他字节值会发生什么?
当然,既然你把256字节的映射写入'加密'文件,它将是孩子的游戏解码;这个方案的安全性可以忽略不计。但是,作为编程练习,它仍然有一些优点。
没有理由捏造整个文件然后逐字节写出来。您可以完美地逐字节读取它,也可以逐字节写入。或者你可以啜饮整个文件,将其映射到原位,然后一次性写入整个文件。一致性在编程中很重要。