论文部分内容阅读
摘 要 网上的文件加密程序很多,像最著名的winrar,winzip等。它们的实现算法相当复杂。同时还有一些简单的加密程序,有的操作虽然简单,却需要配套解密程序;或者是操作繁琐。
关键词 解密;加密;算法;Huffman;自解密;线程
中图分类号:TP309.7 文献标识码:A 文章编号:1671-7597(2015)03-0112-02
1 问题提出
网上的文件加密程序很多,像最著名的winrar,winzip,它们的算法相当复杂。还有一些简单的加密程序,操作虽然简单,却需要配套解密程序;或者是操作繁琐。本人用过许多,效果都不太好。于是本人决定自己开发一个简单的自解密文件加密软件。
2 创作思路
本人觉得Huffman编码是最简单的一种算法,采用它实现自解密的加密文件软件的算法。双击运行程序,输入密码,选择一个文件,会自动生成自解密程序。以后任意运行自解密程序,输入前面加密时输入的密码,则解密出原始文件。
整个软件只有一个程序“可执行文件加密器.exe”,它的自定义资源为一个可执行文件解密器.exe的文件内容。其它3个是VC2013动态链接库。
程序先读入打开文件对话框中选择的文件内容,输入密码,根据文件中的256个字符(0-255)出现的次数,作为各个字符的权值,构造Huffman树和各个字符的Huffman编码。将每个字符换成它对应的Huffman编码,并转换成字节(1个或2个),将加密文件内容先存入输出缓冲区中。
然后依次写入可执行文件解密器.exe(由自定义资源中读取)、无路径的打开文件名、输入的密码(已经由公用SHA1算法加密)、Huffman结构、Huffman加密文件内容、标志,最后是文件名长度+文件名偏移+密码长度+密码偏移+Huffman结构长度+Huffman结构偏移+Huffman加密文件内容长度+Huffman加密文件内容偏移。其中最后这8个整数都是加密的,Huffman加密文件内容也是加密的。
程序通过线程调用来实现大数据量的文件写入,通过不停的等待全局变量g_Finished的值为真,来结束程序运行,弹出成功生成加密文件对话框。
自定义资源(可执行程序解密程序.exe)首先弹出输入密码对话框,输入一个密码。然后读取它自身文件内容,通过标志定位到最后100个字节,找到文件名长度+文件名偏移+密码长度+密码偏移+Huffman结构长度+Huffman结构偏移+Huffman加密文件内容长度+Huffman加密文件内容偏移,实现这8个整数的解密。从自身读出文件名和密码,并和输入密码比较,不同,弹出错误对话框,结束运行。否则读出并填充Huffman结构(Huffman树)。读出加密文件内容到缓冲区,对缓冲区中的字节做解密操作。对缓冲区的加密文件内容中的每一个字节,从Huffman树的根节点开始,根据当前读取字节是’0’还是’1’,相应选择左子树或右子树。如果当前字节找到的左子树指针和右子树指针之和为0,说明找到了叶子节点,读出该字符的原始代码(0-255),累计存入另一个缓冲区中。最后写入“文件名”文件,解密操作成功完成。
3 关键代码
3.1 Huffman加密文件
count = 0;
for (i = 0; i < filesize; i++)
{
uc= (unsigned char)Buffer[i];
length=strlen(hfNode[uc].code);
memset(code,0,sizeof(char)*16);
if(length==8)
strcpy_s(code,hfNode[uc].code);
else if(length<8)
{
for(j=0;j code[j]=hfNode[uc].code[j];
for(j=length;j<8;j++)code[j]=‘0’;
}
else
{
for(j=0;j code[j]=hfNode[uc].code[j];
for(j=length;j<16;j++)code[j]=‘0’;
}
b=b2=0;
for(j=0;j<8;j++)
b|=(code[j]- ‘0’)<<(7-j);
buffer[count++] = b;
if(length > 8)
{
for (j = 8; j < 16; j++)
b2 |= (code[j] - ‘0’) << (15 - j);
buffer[count++] = b2;
}
}
…
Count = count;
}
3.2 写入结构
OF.open(filename2, ios::out | ios::binary);
…
pBuffer=LockResource(hGlobal);
exeBuffer = new char[length];
memcpy(exeBuffer, pBuffer, length);
…
OF.write(exeBuffer, length); 文件名偏移=OF.tellp(),文件名长度=strlen(shortFileName);
OF.write(shortFileName, 文件名长度); .
//写入密码同上
Huffman结构偏移 = OF.tellp(), Huffman结构长度 = sizeof(hfNode[0])*M;
for (i = 0; i < M; i++)
OF.write((char*)&hfNode[i], sizeof(hfNode[i]));
Huffman加密文件内容偏移 = OF.tellp(), Huffman加密文件内容长度 = count;
for(i=0;i {
…
for(j=0;j<4;j++)
{
uc=buffer[i];
uc ^= encbyte[j];
}
buffer[i]=uc;
}
OF.write(buffer, Huffman加密文件内容长度);
…
OF.write(flag, strlen(flag));
文件名长度 -= 173, 文件名偏移 -= 227,…;
OF << 文件名长度 << “ “ << 文件名偏移 << “ “…;
OF.close();
…
g_Finished = true;
}
4 小结
现在很多程序不是算法深奥难懂;就是操作复杂,令人眼花缭乱。其实一个完整清晰、操作简单、功能强大的程序更加适合用户使用。
参考文献
[1]算法分析与设计[M].人民邮电出版社.
[2]数据结构[M].清华大学出版社.
[3]现代计算机常用数据结构和算法[M].机械工业出
版社.
作者简介
童小明(1974-),男,汉族,江西新余人,新余市第十中学高级教师,江西省技术能手,1996年7月毕业于上海铁道大学,计算机应用专业本科学历,精于软件编程、硬件维修、网络维护和网站建设。
袁芳(1982-),女,汉族,江西新余人,新余市第十中学二级教师,大学学历,江西科技师范学院毕业。
关键词 解密;加密;算法;Huffman;自解密;线程
中图分类号:TP309.7 文献标识码:A 文章编号:1671-7597(2015)03-0112-02
1 问题提出
网上的文件加密程序很多,像最著名的winrar,winzip,它们的算法相当复杂。还有一些简单的加密程序,操作虽然简单,却需要配套解密程序;或者是操作繁琐。本人用过许多,效果都不太好。于是本人决定自己开发一个简单的自解密文件加密软件。
2 创作思路
本人觉得Huffman编码是最简单的一种算法,采用它实现自解密的加密文件软件的算法。双击运行程序,输入密码,选择一个文件,会自动生成自解密程序。以后任意运行自解密程序,输入前面加密时输入的密码,则解密出原始文件。
整个软件只有一个程序“可执行文件加密器.exe”,它的自定义资源为一个可执行文件解密器.exe的文件内容。其它3个是VC2013动态链接库。
程序先读入打开文件对话框中选择的文件内容,输入密码,根据文件中的256个字符(0-255)出现的次数,作为各个字符的权值,构造Huffman树和各个字符的Huffman编码。将每个字符换成它对应的Huffman编码,并转换成字节(1个或2个),将加密文件内容先存入输出缓冲区中。
然后依次写入可执行文件解密器.exe(由自定义资源中读取)、无路径的打开文件名、输入的密码(已经由公用SHA1算法加密)、Huffman结构、Huffman加密文件内容、标志,最后是文件名长度+文件名偏移+密码长度+密码偏移+Huffman结构长度+Huffman结构偏移+Huffman加密文件内容长度+Huffman加密文件内容偏移。其中最后这8个整数都是加密的,Huffman加密文件内容也是加密的。
程序通过线程调用来实现大数据量的文件写入,通过不停的等待全局变量g_Finished的值为真,来结束程序运行,弹出成功生成加密文件对话框。
自定义资源(可执行程序解密程序.exe)首先弹出输入密码对话框,输入一个密码。然后读取它自身文件内容,通过标志定位到最后100个字节,找到文件名长度+文件名偏移+密码长度+密码偏移+Huffman结构长度+Huffman结构偏移+Huffman加密文件内容长度+Huffman加密文件内容偏移,实现这8个整数的解密。从自身读出文件名和密码,并和输入密码比较,不同,弹出错误对话框,结束运行。否则读出并填充Huffman结构(Huffman树)。读出加密文件内容到缓冲区,对缓冲区中的字节做解密操作。对缓冲区的加密文件内容中的每一个字节,从Huffman树的根节点开始,根据当前读取字节是’0’还是’1’,相应选择左子树或右子树。如果当前字节找到的左子树指针和右子树指针之和为0,说明找到了叶子节点,读出该字符的原始代码(0-255),累计存入另一个缓冲区中。最后写入“文件名”文件,解密操作成功完成。
3 关键代码
3.1 Huffman加密文件
count = 0;
for (i = 0; i < filesize; i++)
{
uc= (unsigned char)Buffer[i];
length=strlen(hfNode[uc].code);
memset(code,0,sizeof(char)*16);
if(length==8)
strcpy_s(code,hfNode[uc].code);
else if(length<8)
{
for(j=0;j
for(j=length;j<8;j++)code[j]=‘0’;
}
else
{
for(j=0;j
for(j=length;j<16;j++)code[j]=‘0’;
}
b=b2=0;
for(j=0;j<8;j++)
b|=(code[j]- ‘0’)<<(7-j);
buffer[count++] = b;
if(length > 8)
{
for (j = 8; j < 16; j++)
b2 |= (code[j] - ‘0’) << (15 - j);
buffer[count++] = b2;
}
}
…
Count = count;
}
3.2 写入结构
OF.open(filename2, ios::out | ios::binary);
…
pBuffer=LockResource(hGlobal);
exeBuffer = new char[length];
memcpy(exeBuffer, pBuffer, length);
…
OF.write(exeBuffer, length); 文件名偏移=OF.tellp(),文件名长度=strlen(shortFileName);
OF.write(shortFileName, 文件名长度); .
//写入密码同上
Huffman结构偏移 = OF.tellp(), Huffman结构长度 = sizeof(hfNode[0])*M;
for (i = 0; i < M; i++)
OF.write((char*)&hfNode[i], sizeof(hfNode[i]));
Huffman加密文件内容偏移 = OF.tellp(), Huffman加密文件内容长度 = count;
for(i=0;i
…
for(j=0;j<4;j++)
{
uc=buffer[i];
uc ^= encbyte[j];
}
buffer[i]=uc;
}
OF.write(buffer, Huffman加密文件内容长度);
…
OF.write(flag, strlen(flag));
文件名长度 -= 173, 文件名偏移 -= 227,…;
OF << 文件名长度 << “ “ << 文件名偏移 << “ “…;
OF.close();
…
g_Finished = true;
}
4 小结
现在很多程序不是算法深奥难懂;就是操作复杂,令人眼花缭乱。其实一个完整清晰、操作简单、功能强大的程序更加适合用户使用。
参考文献
[1]算法分析与设计[M].人民邮电出版社.
[2]数据结构[M].清华大学出版社.
[3]现代计算机常用数据结构和算法[M].机械工业出
版社.
作者简介
童小明(1974-),男,汉族,江西新余人,新余市第十中学高级教师,江西省技术能手,1996年7月毕业于上海铁道大学,计算机应用专业本科学历,精于软件编程、硬件维修、网络维护和网站建设。
袁芳(1982-),女,汉族,江西新余人,新余市第十中学二级教师,大学学历,江西科技师范学院毕业。