狂自私

导航

RC4算法的实现

c++ 宽字节版本

RC4Enc.h

#pragma once
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <array>
#include <random>
//RC4加密类
class RC4Enc
{
public:
    //KeyLen:密钥长度,取值范围1~256,大于该长度则会取余;小于则会取1;256的倍数则取256
    RC4Enc(int KeyLen);
    /*
    * 由明文产生密文
    * plain_text:明文文件路径
    * key_stream:密钥流文件路径
    * cipher_text:密文文件路径
    * 返回值:失败返回-1,成功返回0
    */
    int encryption(const std::wstring& plain_text, const std::wstring& key_stream, const std::wstring& cipher_text);
private:
    //密钥的最大长度
    const unsigned short MAX_KeyLen{ 256 };
    //状态向量,共256个字符
    std::array<wchar_t, 256>S{ 0 };
    //临时向量,共256个字符
    std::array<wchar_t, 256>Temp{ 0 };
    //密钥长度,取值范围1~256
    unsigned short KeyLen;
    //可变长度密钥
    std::vector<wchar_t>Variable_Length_Key;
    //密钥流
    std::vector<wchar_t>Key_Stream;
    // 非确定性生成器
    std::random_device rd;                        
    // 将随机数种子传递过去,然后使用gen()生成随机数
    std::mt19937 gen{this->rd()};    
    //设置随机数范围
    //std::uniform_int_distribution<> dist(1,256);    
    
protected:
    /*
    初始化状态向量S和临时向量T,供keyStream_func方法调用
    用连续的值初始化数组
    */
    void initial_func();
    /*
    * 排列状态向量S,供keyStream_func方法调用
    * 把数组的值打乱排序
    */
    void range_S_func();
    /*
    * 生成密钥流
    * Len:明文为的长度
    */
    void keyStream_func(unsigned Len);
};
RC4Enc.cpp
#include "RC4Enc.h"
RC4Enc::RC4Enc(int KeyLen) {
    if (KeyLen > 0) {
        this->KeyLen = (KeyLen % this->MAX_KeyLen) == 0 ? this->MAX_KeyLen : KeyLen % this->MAX_KeyLen;
    }
    else {
        this->KeyLen = 1;
    }
    for (unsigned short i{},temp; i < this->KeyLen; i++) {
        temp = this->gen()% this->MAX_KeyLen;
        this->Variable_Length_Key.push_back(static_cast<wchar_t>(temp));
    }
}
void RC4Enc::initial_func() {
    for (unsigned i{}; i < this->MAX_KeyLen; i++) {
        this->S[i] = i;
        this->Temp[i] = this->Variable_Length_Key[i%this->KeyLen];
    }
}
void RC4Enc::range_S_func() {
    unsigned int j{};
    for (unsigned short i{}; i < this->MAX_KeyLen; i++) {
        j = (j + this->S[i] + this->Temp[i]) % this->MAX_KeyLen;
        this->S[i] += this->S[j];
        this->S[j] = this->S[i] - this->S[j];
        this->S[i] -= this->S[j];
    }
}
int RC4Enc::encryption(const std::wstring& plain_text, const std::wstring&key_stream, const std::wstring&cipher_text) {
    std::wifstream w_in;
    std::wofstream w_out,w_out_key_stream;

    w_in.open(plain_text);        //以字符模式读取
    if (!w_in) {
        std::wcout << L"没有被创建\n";
        return -1;
    }
    //获取输入流的长度
    w_in.seekg(0, std::ios::end);
    const int FileLen = static_cast<int>(w_in.tellg());
    w_in.seekg(0, std::ios::beg);

    //生成密钥流
    this->keyStream_func(FileLen);

    //明文内容读取入bits中
    wchar_t* bits = new wchar_t[FileLen] {};
    w_in.read(bits, FileLen);
    w_in.close();

    w_out.open(cipher_text, std::ios::binary);    //以二进制模式写入
    //将明文按照字符依次与密钥流亦或输出到密文文件中
    wchar_t temp_wchar{};
    for (int i{}; i < FileLen; i++) {
        //std::cout << std::hex << bits[i];
        //std::cout << '^';
        //std::cout << std::hex << this->Variable_Length_Key[i];
        //std::cout << "==>";
        //std::cout << std::hex << (bits[i] ^ this->Variable_Length_Key[i]);
        //std::cout << std::endl;
        temp_wchar = bits[i] ^ this->Variable_Length_Key[i];
        w_out << temp_wchar;
    }
    w_out.close();

    //秘钥流写入到文件
    w_out_key_stream.open(key_stream, std::ios::binary);    //以二进制模式写入
    for (int i{}; i < FileLen; i++) {
        temp_wchar = this->Variable_Length_Key[i];
        w_out_key_stream << temp_wchar;
    }
    w_out_key_stream.close();
    return 0;
}
void RC4Enc::keyStream_func(unsigned Len) {
    this->initial_func();        //用连续的值初始化数组
    this->range_S_func();        //把数组的值打乱排序

    unsigned i{}, j{}, t{};
    while (Len--)
    {
        i = (i + 1) % this->MAX_KeyLen;
        j = (j + this->S[i]) % this->MAX_KeyLen;

        this->S[i] += this->S[j];
        this->S[j] = this->S[i] - this->S[j];
        this->S[i] -= this->S[j];

        t = (this->S[i] + this->S[j]) % this->MAX_KeyLen;
        this->Variable_Length_Key.push_back(this->S[t]);
    }
}

RC4Dec.h

#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <array>
#include <fstream>
#include <random>
/*RC4解密类*/
class RC4Dec
{
public:
    /*
    * key_stream:密钥流文件路径
    * cipher_text:密文文件路径
    */
    RC4Dec(const std::wstring& key_stream, const std::wstring& cipher_text);
    /*解密方法
    * res:保存解密后的明文的文件路径
    */
    void decryption(const std::wstring&res);
private:
    std::wstring cipherText, keyStream;
};

RC4Dec.cpp

#include "RC4Dec.h"
void RC4Dec::decryption(const std::wstring& res) {
    std::wifstream w_in_key_stream, w_in_cipher_text;
    std::wofstream w_out;

    w_in_key_stream.open(this->keyStream, std::ios::binary);    //以二进制模式读取
    w_in_cipher_text.open(this->cipherText, std::ios::binary);    //以二进制模式读取

    //计算密文长度
    w_in_cipher_text.seekg(0, std::ios::end);
    const unsigned FileLen = static_cast<unsigned>(w_in_cipher_text.tellg());
    w_in_cipher_text.seekg(0, std::ios::beg);

    //读入密钥流
    wchar_t* bitKey = new wchar_t[FileLen] {0};
    w_in_key_stream.read(bitKey, FileLen);
    w_in_key_stream.close();

    //读取密文
    wchar_t *bitCip = new wchar_t[FileLen]{0};
    w_in_cipher_text.read(bitCip, FileLen);
    w_in_cipher_text.close();

    //解密后结果输出到解密文件中
    w_out.open(res);        //以字符模式写入
    wchar_t temp_char{};
    std::wstring Text;
    for (unsigned i{}; i < FileLen; i++) {
        temp_char = (bitKey[i] ^ bitCip[i]);
        //std::cout << std::hex << bitKey[i];
        //std::cout << '^';
        //std::cout << std::hex << bitCip[i];
        //std::cout << "==>";
        //std::cout << std::hex << static_cast<unsigned>(temp_char);
        //std::cout << std::endl;
        if (temp_char) {    //不将\0字符写入到文件中
            Text += bitKey[i] ^ bitCip[i];
        }
    }
    w_out << Text;
    w_out.close();
}
RC4Dec::RC4Dec(const std::wstring& key_stream, const std::wstring& cipher_text) {
    cipherText = cipher_text;
    keyStream = key_stream;
}

 

调用

#include <iostream> 
#include "RC4Dec.h"
#include "RC4Enc.h"

int main()
{
    RC4Enc rc4enc(16);
    if (rc4enc.encryption(L"明文.txt", L"秘钥流.txt", L"密文.txt")) {
        std::cout << "RC4 加密失败!" << std::endl;
        return -1;
    }
    std::cout << "RC4 加密成功!" << std::endl;

    RC4Dec rc4dec(L"秘钥流.txt", L"密文.txt");
    rc4dec.decryption(L"解密文件.txt");

    std::cout << "RC4 解密成功!" << std::endl;
}

 

posted on 2022-08-31 15:47  狂自私  阅读(235)  评论(0编辑  收藏  举报