今天信息安全体系结构布置的作业,对电脑中的文件进行一个简单的加密,要求使用仿射密码,刚写今天也该写这个了,那么就开始吧!
仿射密码运用到了乘法逆元这一概念,具体请百度
大概的意思是,a*b % x = 1,那么,c % x = a*b*c % x,加密也就是m = a*c%x,解密也就是c = b*m%c = b*a*c%x = c,应该是很简单的东西
那么剩下的问题就是如何对计算机中的文件进行加密了。虽然计算机中的文件有很多种格式,但是储存在计算机中都是以二进制的形式存在。并且计算机种的最小寻址单元是字节,所以如果按字节进行加密的话,是不会出现剩余小于8位的文件未读取的情况出现的。那么思路就很清晰了。即:
将计算机中的文件统统视为二进制进行处理,对每一字节进行加密解密即可。
这里还需要考虑的就是,我们的x应该取多少。很明显,因为我们是按照字节进行处理,也就是8位,那么算过来,11111111=256,于是乎x我取了一个257.但是在中间出现了一些问题,就是如果读取的那个字节刚好是0101 1000 = 58,58*31%257 = 256 = 1111 1111,但是实际上确实得到了 0000 0000,这点不太懂,最后迫不得已,对于加密文件使用了2字节的密文来保存1字节的明文,这点还有待改进。各位要是有知道的请务必告知。
那么直接上代码,Xcode和VS2013编译均通过且能正常使用。
//
// main.cpp
// Cryptography
//
// Created by zhou yi on 14-9-4.
// Copyright (c) 2014年 edward. All rights reserved.
//
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Affinecipher
{
string originalFileName;
string encryptedFileName;
public:
void setOriginalFileName(string fileName)
{
originalFileName = fileName;
};
void setEncryptedFileName(string fileName)
{
encryptedFileName = fileName;
};
string getOriginalFileName()
{
return originalFileName;
}
string getEncryptedFileName()
{
return encryptedFileName;
};
void encrypte()
{
ofstream log("Log.txt", ios::app);
if ( !originalFileName.length() || !encryptedFileName.length() )
{
log<<"original file name or encrypted file name can't be empty"<<endl;
return ;
}
ifstream inf( originalFileName, ios::binary);
ofstream ouf( encryptedFileName, ios::binary);
if( !inf || !ouf )
{
log<<"open files faild"<<endl;
return ;
}
int *p = new int();
int *tp = new int();
while ( inf.read((char *) p, 1) )
{
*tp = ( *p * 31 ) % 257;
ouf.write( (char *)tp, 2);
}
inf.close();
ouf.close();
};
void decrypte()
{
ofstream log("Log.txt", ios::app);
if ( !originalFileName.length() || !encryptedFileName.length() )
{
log<<"original file name or encrypted file name can't be empty"<<endl;
return ;
}
ifstream inf( originalFileName, ios::binary);
ofstream ouf( encryptedFileName, ios::binary);
if( !inf || !ouf )
{
log<<"open files faild"<<endl;
return ;
}
int *p = new int();
int *tp = new int();
while ( inf.read((char *)p, 2) )
{
*tp = ( *p * 199 ) % 257;
ouf.write( (char *)tp, 1);
}
inf.close();
ouf.close();
}
};
int main()
{
Affinecipher af;
string originalFileName, encrypteFileName;
cin>>originalFileName; //输入原文件名
af.setOriginalFileName(originalFileName);
cin>>encrypteFileName; //加密后文件名
af.setEncryptedFileName(encrypteFileName);
af.encrypte(); //加密
af.setOriginalFileName(encrypteFileName);
cin>>encrypteFileName; //解密文件名
af.setEncryptedFileName(encrypteFileName);
af.decrypte(); //解密
}
以上为我脑残时候的想法
那么纠正一下,1111 1111 = 255,所以x的选择应该是256,a选择31的时候,b就应该是223,修改之后呢,之前说的两字节问题也不存在了,此处应有掌声,啪啪啪啪啪啪
//
// main.cpp
// Cryptography
//
// Created by zhou yi on 14-9-4.
// Copyright (c) 2014年 edward. All rights reserved.
//
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Affinecipher
{
string originalFileName;
string encryptedFileName;
public:
void setOriginalFileName(string fileName)
{
originalFileName = fileName;
};
void setEncryptedFileName(string fileName)
{
encryptedFileName = fileName;
};
string getOriginalFileName()
{
return originalFileName;
}
string getEncryptedFileName()
{
return encryptedFileName;
};
void encrypte()
{
ofstream log("Log.txt", ios::app);
if ( !originalFileName.length() || !encryptedFileName.length() )
{
log<<"original file name or encrypted file name can't be empty"<<endl;
return ;
}
ifstream inf( originalFileName, ios::binary);
ofstream ouf( encryptedFileName, ios::binary);
if( !inf || !ouf )
{
log<<"open files faild"<<endl;
return ;
}
int *p = new int();
int *tp = new int();
while ( inf.read((char *) p, 1) )
{
*tp = ( *p * 31 ) % 256;
ouf.write( (char *)tp, 1);
}
inf.close();
ouf.close();
};
void decrypte()
{
ofstream log("Log.txt", ios::app);
if ( !originalFileName.length() || !encryptedFileName.length() )
{
log<<"original file name or encrypted file name can't be empty"<<endl;
return ;
}
ifstream inf( originalFileName, ios::binary);
ofstream ouf( encryptedFileName, ios::binary);
if( !inf || !ouf )
{
log<<"open files faild"<<endl;
return ;
}
int *p = new int();
int *tp = new int();
while ( inf.read((char *)p, 1) )
{
*tp = ( *p * 223 ) % 256;
ouf.write( (char *)tp, 1);
}
inf.close();
ouf.close();
}
};
int main()
{
Affinecipher af;
string originalFileName, encrypteFileName;
cin>>originalFileName; //输入原文件名
af.setOriginalFileName(originalFileName);
cin>>encrypteFileName; //加密后文件名
af.setEncryptedFileName(encrypteFileName);
af.encrypte(); //加密
af.setOriginalFileName(encrypteFileName);
cin>>encrypteFileName; //解密文件名
af.setEncryptedFileName(encrypteFileName);
af.decrypte(); //解密
}