密码学学习记录(二)古典密码学之仿射密码

今天信息安全体系结构布置的作业,对电脑中的文件进行一个简单的加密,要求使用仿射密码,刚写今天也该写这个了,那么就开始吧!

仿射密码运用到了乘法逆元这一概念,具体请百度

大概的意思是,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();                            //解密
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值