上一篇文章写完以后,收到了很多朋友的私信,希望我能写出一个较为完善的利用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等多种文件,测试均没有问题。

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

如何用C语言简单加密文件+相关推荐

  1. 如何用脚本创建一个加密文件夹

    要用脚本创建一个加密文件夹,首先需要有一个脚本语言的编辑器,比如 Python.然后,你需要使用 Python 的 os 模块来创建文件夹.例如,可以使用 os.mkdir 函数来创建文件夹,如下所示 ...

  2. 如何用c语言从txt文件中读取数据

    用C语言从txt文件中读取数据,可以使用C标准库文件自带的文件接口函数进行操作. 一.打开文件: FILE *fopen(const char *filename, const char *mode) ...

  3. 如何用c语言编写工程文件夹,利用makefile实现c语言项目编译

    本周操作系统课的实验是用c语言实现10个进程调度算法.这个项目中有多个.h头文件和.c源文件,利用makefile可以很轻松地找到所有项目文件之间的关系并实现编译. 虽然makefile的基本框架学校 ...

  4. c语言实现文件数据删除视频,如何用c语言实现删除文件中指定的数据;例如

    匿名用户 1级 2012-05-21 回答 你的描述不清晰,B1和B2两个结构数组,到底要删除哪个?B[2]是肯定不对的,这两个数组的长度都是2,下标只能是0和1,即B1[0], B1[1], B2[ ...

  5. c 语言生成json 文件,如何用c语言反序列化JSON文件#

    如果密钥不同,如何反序列化JSON文件,从key1到keyN?当我使用python时,这很简单, import pandas as pdmyJson = pd.json.loads(json) 只是用 ...

  6. 如何用C语言清空特定文件夹中的所有文件

    最近笔者在做一个有关计算机视觉的项目,需要对提前的视频帧进行实验,当数据量很大且文件夹中的子文件夹和文件很多时,手工删除这些文件不现实,笔者今天写了一个程序,通过机器自动删除所有相关文件,十分快速,删 ...

  7. Windows下如何用C语言清空特定文件夹中的所有文件

    #include "iostream.h"    //由于该博客系统发布是不能显示正常,代码如需调试,只需将改成""即可 #include "stri ...

  8. C语言简单实现文件传输

    为了实现文件传输,我们需要一个服务端跟一个客户端,再用一个通道把服务器跟客户端连接起来. 实现方式:socket网络编程,采用TCP/IP协议 1.首先呢,拍爱情片肯定少不了男主女主,所以我们需要准备 ...

  9. 如何用C语言对文件进行简单加密

    最近在完成大作业的时候需要实现一个用C语言对文件进行简单加密的操作,这里主要用的加密思路是破坏文件头,使得系统无法识别文件从而进行加密,最初的思路是将用户输入的加密口令转成ASCII码,再与文件头数据 ...

最新文章

  1. linux文件传输常用方法
  2. SpringCloud实战4-Hystrix线程隔离请求缓存请求合并
  3. 【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
  4. 武林外史java游戏,武林外史_网络游戏专区_腾讯游戏频道
  5. Oracle提供的序号函数
  6. [ZZ]关于内存中栈和堆的区别
  7. Luogu 1970 NOIP2013 花匠 (贪心)
  8. python fromarray_python --- 之pil image.fromarray
  9. java就业凉_【哔哩哔哩】秋招凉经 Java篇
  10. 钉钉 e应用 mysql_钉钉E应用入门总结
  11. Nginx+uwsgi+Django项目部署后,url长度限制修改
  12. 2020年 2月 省市区sql(一)
  13. SIM868_GNSS结果解析
  14. C语言实现银行管理系统
  15. 【产品】 产品设计:ID工业设计、MD结构设计、HW硬件设计和SW软件设计详解
  16. oTree学习教程(七)Apps rounds
  17. 如何将M4A格式的音频转换为MP3格式?只需一步搞定
  18. 关于android各平台上架心得
  19. centos mysql 5.2.3 编译安装_在CentOS上编译安装MySQL 5.7.13步骤详解
  20. 浅析“高内聚,低耦合”

热门文章

  1. 对互联网VC的10点看法
  2. Spark 入门简介
  3. 公安局计算机岗位应知应会综合基础知识,事业单位考试计算机综合知识基础知识真题...
  4. Golang | 优雅地定义枚举类型
  5. QT QTextEdit添加文字的方式
  6. 计算机应用基础试题操作题,计算机应用基础期末考试操作题.doc
  7. 基于大数据的银行反欺诈的分析报告 【转载,可用于风控系统架设借鉴】
  8. C#基于 iTextSharp.text.pdf 实现PDF水印添加功能
  9. 【Kafka】kafka架构
  10. golang获取时间所在周的起止时间