如何用C语言简单加密文件+

上一篇文章写完以后,收到了很多朋友的私信,希望我能写出一个较为完善的利用C语言简单加密文件的代码,今天花了点时间终于调试完了,相比于上一篇文章的代码的话这里做了一些改进:

  • 1.加密文件的数据改为原文件数据的十分之一,这样将摆脱文件大小的限制
  • 2.使用用户口令对需加密数据进行循环异或操作,增强了加密的安全性
  • 3.为用户完善了任意路径文件的加密解密操作,增强用户体验

看过我上一篇文章的朋友应该知道,上一次我们只对文件头的前20个字节的数据进行加密,其实这个加密的范围是会受到文件大小的影响的,这一次我们加密文件数据的十分之一,将可以不受任意文件大小的影响,并且上一次的代码中我们让用户输入123,并使每个文件数据与123进行异或,这一次我们允许用户输入10个以内的任意字符(例如:password),并且使文件的第一个数据与‘p’所对应的ASCII码进行异或,第二个数据与‘a’所对应的ASCII码进行异或,并以此类推,将所需加密的数据与用户加密口令进行循环异或,这将极大的增强加密文件的安全性。
需要了解我上一篇文章的朋友可以看:C语言简单加密文件

以下是具体实现的代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char file_to_encrypto[100];   //需要加密的文件路径及名称 
char file_to_decrypto[100];   //需要解密的文件路径及名称 
char encrypted_file[50]="encrypted";//加密后的部分文件名 
char decrypted_file[50]="decrypted";//解密后的部分文件名 
char password[10];     //用户输入的密码 
char temp;       //非加密部分的临时数据 
unsigned int length;  //储存原文件长度 
void encrypto()
{
 printf("请输入您需要加密文件的完整路径:\n");
 scanf("%100s",file_to_encrypto);  //输入需加密文件的完整路径及名称 
 FILE *fp1=fopen(file_to_encrypto,"rb"),*fp2=NULL;  //以rb方式打开需加密的文件 
 if(fp1==NULL)
 {
  printf("打开文件失败!请检查您的文件路径是否正确\n");
 }else{
  fseek(fp1,0,2);   //使光标移动到文件末尾 
  length=ftell(fp1);  //返回文件的大小 
  unsigned char* data=(unsigned char*)malloc(length/10); //我们这里加密原文件数据的十分之一 
  int i,j;
  for(i=strlen(file_to_encrypto)-1;i>0;i--) //这里进行一个文件格式(后缀名)的截取 
  {     
   if(file_to_encrypto[i]=='.')  //从文件名末尾往前查找到第一个'.'号,将其后的文件后缀名添加到加密文件民的末尾 
   {         //若需加密文件本身没有文件后缀名,则加密后文件名也没有后缀名,即文件名为 encrypted 
    int p=0;
    for(j=i;j<strlen(file_to_encrypto);j++,p++) //文件后缀名的截取 
    {
     encrypted_file[9+p]=file_to_encrypto[j]; 
    }
    break;
   }
  }
  rewind(fp1);   //放回文件光标到文件头 
  for(i=0;i<length/10;i++)  //读取原文件十分之一的数据到data 
  {
   fread(&data[i],sizeof(unsigned char),1,fp1);
  }
  printf("请输入您的加密口令(不超过10位):\n");
  scanf("%10s",password);
  for(i=0;i<(length/10)/strlen(password)+1;i++)  //将加密口令的每一位与需加密数据的每一位循环异或,保证加密的安全性 
  {
   for(j=0;j<strlen(password) && i*strlen(password)+j<(length/10);j++)
   {
    data[i*strlen(password)+j]^=password[j];
   }
  }
   
  fp2=fopen(encrypted_file,"wb"); //以wb方式打开二进制文件,注意不可以用w方式! 
  if(fp2==NULL)
  {
   printf("创建加密文件失败!\n");
  }else{
   for(i=0;i<length/10;i++)   //首先将加密后的数据写入文件 
   {
    fwrite(&data[i],sizeof(unsigned char),1,fp2);
   }
   rewind(fp1); 
   fseek(fp1,length/10,0);  //使文件光标移动到文件大小的十分之一处 
   while(i<length)    //将未加密的文件数据写入加密文件,i从length/10开始,所以不需要重置i的值 
   {
    fread(&temp,sizeof(unsigned char),1,fp1);  //循环写入数据 
    fwrite(&temp,sizeof(unsigned char),1,fp2);
    i++;
   }
   printf("加密成功!加密文件(encrypted)已保存到您当前目录下\n");
   printf("请牢记您的加密口令!\n");
   free(data); 
   fclose(fp1);
   fclose(fp2);
   getchar();
   getchar(); 
  }
 }
 
} 
void decrypto()
{
 printf("请输入您需要解密文件的完整路径:\n");
 scanf("%100s",file_to_decrypto);  //输入需要解密的文件路径及名称 
 FILE *fp1=fopen(file_to_decrypto,"rb"),*fp2=NULL;
 if(fp1==NULL)
 {
  printf("打开文件失败!请检查您的文件路径是否正确\n");
 }else{
  fseek(fp1,0,2);
  length=ftell(fp1); //取得文件长度储存在length中 
  unsigned char* data=(unsigned char*)malloc(length/10);//开辟动态内存 
  int i,j;
  for(i=strlen(file_to_decrypto)-1;i>0;i--)  //截取文件的后缀名 
  {
   if(file_to_decrypto[i]=='.')
   {
    int p=0;
    for(j=i;j<strlen(file_to_decrypto);j++,p++)
    {
     decrypted_file[9+p]=file_to_decrypto[j]; 
    }
    break;
   }
  }
  rewind(fp1);  //读取需解密的文件数据,即原文件数据长度的十分之一 
  for(i=0;i<length/10;i++)
  {
   fread(&data[i],sizeof(unsigned char),1,fp1);
  }
  printf("请输入您的加密口令(不超过10位):\n");
  scanf("%10s",password);
  for(i=0;i<(length/10)/strlen(password)+1;i++)  //将需解密的数据与用户口令循环异或 
  {
   for(j=0;j<strlen(password) && i*strlen(password)+j<(length/10);j++)
   {
    data[i*strlen(password)+j]^=password[j];
   }
  }
  fp2=fopen(decrypted_file,"wb"); //创建解密文件 
  if(fp2==NULL)
  {
   printf("创建解密文件失败!\n");
  }else{
   for(i=0;i<length/10;i++)  //首先写入解密后的数据 
   {
    fwrite(&data[i],sizeof(unsigned char),1,fp2);
   }
   rewind(fp1); 
   fseek(fp1,length/10,0);//使光标移动到文件数据的十分之一处 
   while(i<length)  //将未解密的数据写入 
   {
    fread(&temp,sizeof(unsigned char),1,fp1);
    fwrite(&temp,sizeof(unsigned char),1,fp2);
    i++;
   } 
   printf("解密成功!解密文件(decrypted)已保存到您当前目录下\n");
   free(data); 
   fclose(fp1);
   fclose(fp2);
   getchar();
   getchar(); 
  }
 }
 
}
int main()
{
 int choice=0;
 while(1){
  system("color 0a");
  system("cls");
  printf("欢迎使用文件加密系统!\n");
  printf("请输入您的选择\n");
  printf("1.加密文件   2.解密文件   3.退出系统\n");
  scanf("%d",&choice);
  while(choice != 1 && choice != 2 && choice !=3)
  {
   printf("输入选择有误!请重新输入:");
   scanf("%d",&choice);
  } 
  switch (choice)
  {
   case 1: encrypto();
     break;
   case 2: decrypto();
     break;
   case 3: printf("非常感谢您的使用!期待与您下次相见\n");
     system("taskkill -f -im 文件加解密系统.exe");
     break; 
  } 
 }
 return 0;
}

这里需要提醒的是,退出系统为另附功能,若您需要使用该功能,需要将system(“taskkill -f -im 文件加解密系统.exe”);中的“文件加解密系统.exe”换成您自己的程序名称,否则将导致退出程序失败。

我们这里以加解密当前路径下的一张图片为例:
在这里插入图片描述我们首先查看这三张图片的属性:
在这里插入图片描述
可以看到三张图片的大小一致,说明数据不存在丢失的情况
然后我们利用winhex查看文件数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到加密后的文件数据已经难以识别,而解密后的文件数据与原文件一致,我们这里验证我们的异或算法,将原文件的第一个字节0x42拿去和加密文件的第一个字节0x36进行异或,并以此将原文件的第二个字节(0x4d)第三个字节(0xa2)第四个字节(0xee)分别与加密文件的第二、三、四个字节进行异或,可以得到
在这里插入图片描述
他们分别就是我们输入的加密口令"test",有兴趣的朋友可以验证更多的数据位,会发现异或出的结构是test的循环,因此若我们只得到加密文件,在没有我们的加密算法的情况下,几乎无法修复原文件,保证了加密的安全性。

我这里也在本地多次实验,加密了zip,rar,doc等多种文件,测试均没有问题。

以上代码仅供参考,大家可以根据自己的需要进行修改和补充,希望能为各位抛砖引玉。
若还有存在疑惑的地方,欢迎留言或评论。

  • 36
    点赞
  • 146
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
### 回答1: 好的,我可以给你一些用 C 语言实现简单加密的思路。 首先,你需要有一个加密算法。最简单加密算法之一就是按字母表顺序移位。例如,如果你想将所有字母向后移动 3 个位置,那么字母 A 就会变成字母 D,字母 B 就会变成字母 E,以此类推。 其次,你需要读入输入文本,并将其转换为你要加密的字符串。你可以使用 C 语言的 fgets 函数来读取一行文本,或者使用 scanf 函数来读取单个字符。 然后,你可以使用循环来遍历字符串,并对每个字符执行加密操作。你可以使用 C 语言中的 if 语句来检查字符是否为字母,并使用其他语句来执行移位操作。 最后,你可以使用 printf 函数将加密后的文本输出到屏幕上,或者使用 fprintf 函数将其写入文件中。 这是一个简单的例子,其中包含了这些步骤: ``` #include <stdio.h> #include <ctype.h> #define SHIFT 3 int main(void) { char ch; printf("Enter message to be encrypted: "); while ((ch = getchar()) != '\n') { if (isalpha(ch)) { if (isupper(ch)) { ch = ((ch - 'A') + SHIFT) % 26 + 'A'; } else { ch = ((ch - 'a') + SHIFT) % 26 + 'a'; ### 回答2: 使用C语言实现简单加密可以通过凯撒密码方法来实现。凯撒密码是一种最简单加密算法,也叫移位密码。具体实现步骤如下: 1. 定义一个字符串来存储要加密的消息。 2. 定义一个整型变量来表示移位的位数。 3. 使用循环遍历字符串中的每个字符。 4. 将每个字符转换为ASCII码。 5. 对ASCII码进行移位操作,即将每个字符的ASCII码加上移位位数。 6. 如果移位后的ASCII码超过了字母的范围,即大于122或者大于90,需要将该ASCII码重新归位到字母范围内,即减去26。 7. 将移位后的ASCII码转换为字符。 8. 将加密后的字符存储到一个新的字符串中。 9. 将新的字符串输出,即为加密后的消息。 示例代码如下: ```c #include <stdio.h> void encrypt(char* message, int shift) { int i = 0; while (message[i] != '\0') { char c = message[i]; if (c >= 'a' && c <= 'z') { c = ((c - 'a') + shift) % 26 + 'a'; } else if (c >= 'A' && c <= 'Z') { c = ((c - 'A') + shift) % 26 + 'A'; } message[i] = c; i++; } } int main() { char message[] = "Hello, World!"; int shift = 3; encrypt(message, shift); printf("加密后的消息:%s\n", message); return 0; } ``` 以上代码实现一个简单的凯撒密码加密算法。通过指定移位位数,可以将原始消息加密后输出。在本示例中,原始消息是"Hello, World!",移位位数为3,加密后的消息就是"Khoor, Zruog!"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

monster663

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值