C++实现DES算法(64位二进制位加密)

本文深入解析了DES(数据加密标准)算法的实现细节,包括64位数据的加密与解密流程,秘钥生成,置换操作,S盒置换,以及异或运算等核心步骤。通过具体的代码示例展示了如何使用C++实现DES算法。
#pragma once
#include<vector>
#include<string>
#include<math.h>
#include <iostream>
using namespace std;

enum { ENCRYPT = 0, DECRYPT = 1 };
vector<bool> des_64bit(vector<bool>&, vector<bool>&, int);//64比特数据加密
void des_encrypt(vector<bool>&, vector<bool>&, vector<vector<bool>>&);
void des_decrypt(vector<bool>&, vector<bool>&, vector<vector<bool>>&);
vector<vector<bool>> calculate_sub_key(vector<bool>&);//计算16个子秘钥
void permutation(vector<bool>& , const vector<int>&);//置换
void rotate_left(vector<bool>&, int);
void s_box_substitution(vector<bool>& Rint);
void Print(vector<bool>& v);
vector<bool> XOR(vector<bool>& a, vector<bool>& b);
vector<bool> str_64bit_2_vector(string& t);//64位比特串转bool数组

//初始置换表IP(64位)
const static vector<int> IP_Table = 
{
    58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
    62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
    57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
    61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7
};
//逆初始置换表IP^-1(64位)
const static vector<int> Inverse_IP_Table = 
{
    40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,
    38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,
    36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,
    34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25
};
//秘钥置换选择表1(56位)
const static vector<int> IP_Table_Key_56 = 
{
    57,49,41,33,25,17,9,1,58,50,42,34,26,18,
    10,2,59,51,43,35,27,19,11,3,60,52,44,36,
    63,55,47,39,31,23,15,7,62,54,46,38,30,22,
    14,6,61,53,45,37,29,21,13,5,28,20,12,4
};
//秘钥置换选择表2(48位)
const static vector<int> IP_Table_Key_48 = 
{
    14,17,11,24,1,5,3,28,15,6,21,10,
    23,19,12,4,26,8,16,7,27,20,13,2,
    41,52,31,37,47,55,30,40,51,45,33,48,
    44,49,39,56,34,53,46,42,50,36,29,32
};
//秘钥旋转次数表
const static vector<int> Rotations_Table =
{
    1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
//扩展置换表E(48位)
static const vector<int> E_Table = 
{
    32,1,2,3,4,5,4,5,6,7,8,9,
    8,9,10,11,12,13,12,13,14,15,16,17,
    16,17,18,19,20,21,20,21,22,23,24,25,
    24,25,26,27,28,29,28,29,30,31,32,1
};
//置换P(32位)
static const vector<int> P_Table = 
{
    16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,
    2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25
};
// S盒
static const vector<vector<vector<int>>> S_Box=
{
    // S1 
    {{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
    {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
    {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
    {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},
    //S2
    {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
    {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
    {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
    {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},
    //S3
    {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
    {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
    {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
    {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},
    //S4
    {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
    {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
    {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
    {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},
    //S5
    {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
    {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
    {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
    {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},
    //S6
    {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
    {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
    {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
    {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},
    //S7
    {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
    {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
    {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
    {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},
    //S8
    {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
    {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
    {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
    {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}
};
#include "DES.h"

void Print(vector<bool>& v)
{
    for (auto a : v)
        cout << a;
    cout << endl;
}

//64位比特串转bool数组
vector<bool> str_64bit_2_vector(string& text)
{
    vector<bool> Tp;
    for (auto b : text)
    {
        if (b == '0')
            Tp.push_back(0);
        else
            Tp.push_back(1);
    }
    return Tp;
}

//计算16个子秘钥
vector<vector<bool>> calculate_sub_key(vector<bool>& Key)
{
    permutation(Key, IP_Table_Key_56);//秘钥置换选择1
    vector<bool> Ci;//C0
    vector<bool> Di;//D0
    //C0和D0初始化
    for (unsigned int i = 0; i < Key.size(); i++)
    {
        if (2 * i < Key.size())
            Ci.push_back(Key[i]);
        else
            Di.push_back(Key[i]);
    }
    vector<vector<bool>> Ki;
    for (int i = 0; i < 16; i++)
    {
        int n = Rotations_Table[i];//左移次数
        rotate_left(Ci, n);//Ci+1循环左移n位
        rotate_left(Di, n);//Di+1循环左移n位
        //合并Ci+1和Di+1为Ki+1
        vector<bool> K = Ci;
        for (auto b : Di)
            K.push_back(b);
        permutation(K, IP_Table_Key_48);//秘钥置换选择2
        Ki.push_back(K);
    }
    return Ki;
}

//置换
void permutation(vector<bool>& Binary_String_64Bits, const vector<int>& Table) {
    vector<bool> Tp;
    Tp.assign(Table.size(), 0);//置换后长度与置换表长度一致
    for (unsigned int i = 0; i < Table.size(); i++)
        Tp[i] = Binary_String_64Bits[Table[i] - 1];
    Tp.swap(Binary_String_64Bits);
    Binary_String_64Bits.resize(Table.size());
}

//左移n位
void rotate_left(vector<bool>& String, int n) {
    vector<bool> Tp;
    int L = String.size();
    Tp.assign(L, 0);
    for (int i = 0; i < L; i++)
        Tp[i] = String[(i + n + L) % L];
    Tp.swap(String);
}

//异或
vector<bool> XOR(vector<bool>& a, vector<bool>& b) 
{
    vector<bool> RES;
    for (unsigned int i = 0; i < a.size(); i++)
        RES.push_back(a[i] ^ b[i]);
    return RES;
}

//S盒置换  48比特→32比特
void s_box_substitution(vector<bool>& Rint)
{
    vector<vector<bool>> Bi;//存放8个6比特串
    vector<bool> Tp;
    for (unsigned int i = 0; i < 8; i++)
    {
        for (unsigned int j = 0; j < 6; j++)
            Tp.push_back(Rint[6 * i + j]);
        Bi.push_back(Tp);
        Tp.clear();
    }
    //S盒置换
    vector<bool> RES;
    RES.assign(32, 0);
    for (unsigned int i = 0; i < 8; i++)
    {
        //6比特→4比特
        //计算行,看6比特的第一位和最后一位
        int Row = Bi[i][0] * 2 + Bi[i][5];
        //计算列,看6比特的中间四位
        int Col = Bi[i][1] * 8 + Bi[i][2] * 4 + Bi[i][3] * 2 + Bi[i][4];
        //根据S盒表找到值
        int S_Val = S_Box[i][Row][Col];
        //计算值对应的二进制数
        for (int x = 0; x < 4; x++)
        {
            RES[3 - x + 4 * i] = S_Val % 2;
            S_Val /= 2;
        }   
    }
    RES.swap(Rint);
}

//DES加密
void des_encrypt(vector<bool>& Li, vector<bool>& Ri, vector<vector<bool>>& Ki)
{
    for (unsigned int i = 0; i < 16; i++)
    {
        vector<bool> R = Ri;//复制Ri
        //求f(Ri-1,Ki)
        permutation(Ri, E_Table);//Ri从32位扩展到48位
        vector<bool> Rint = XOR(Ri, Ki[i]);//Ri和Ki异或得到中间值Rint
        s_box_substitution(Rint);//Rint进行S盒替换得到32位
        permutation(Rint, P_Table);//P盒置换
        //最终得到Rint=f(Ri-1,Ki)

        vector<bool> Tp = XOR(Rint, Li);//Ri=Li-1xorf(Ri-1,Ki)
        Ri.swap(Tp);
        Li.swap(R);//Li=Ri-1       
    }
}

//DES解密
void des_decrypt(vector<bool>& Li, vector<bool>& Ri, vector<vector<bool>>& Ki)
{
    for (int i = 15; i > -1; i--)
    {
        vector<bool> R = Ri;//复制Ri
        //求f(Ri-1,Ki)
        permutation(Ri, E_Table);//Ri从32位扩展到48位
        vector<bool> Rint = XOR(Ri, Ki[i]);//Ri和Ki异或得到中间值Rint
        s_box_substitution(Rint);//Rint进行S盒替换得到32位
        permutation(Rint, P_Table);//P盒置换
        //最终得到Rint=f(Ri-1,Ki)

        vector<bool> Tp = XOR(Rint, Li);//Ri=Li-1xorf(Ri-1,Ki)
        Ri.swap(Tp);
        Li.swap(R);//Li=Ri-1       
    }
}

//64比特数据加密
vector<bool> des_64bit(vector<bool>& Text, vector<bool>& Key, int Mode)
{
    permutation(Text, IP_Table);//初始置换
    vector<vector<bool>> Ki = calculate_sub_key(Key);
    vector<bool> Li;//L0
    vector<bool> Ri;//R0
    //L0和R0初始化
    for (unsigned int i = 0; i < Text.size(); i++)
    {
        if (2 * i < Text.size())
            Li.push_back(Text[i]);
        else
            Ri.push_back(Text[i]);
    }
    //16轮加密/解密
    if (Mode == ENCRYPT)
        des_encrypt(Li, Ri, Ki);
    else if (Mode == DECRYPT)
        des_decrypt(Li, Ri, Ki);
    //拼接R16和L16
    for (unsigned int i = 0; i < Text.size(); i++)
    {
        if (i < Ri.size())
            Text[i] = Ri[i];
        else
            Text[i] = Li[i - Ri.size()];
    }
    permutation(Text, Inverse_IP_Table);//最终置换(初始置换的逆置换)

    return Text;
}
#include"DES.h"
int main() 
{
    string Text_Binary = "0000000100100011010001010110011110001001101010111100110111101111";
    string Key_Binary = "0000000100100011010001010110011110001001101010111100110111101111";

    cout << "明文" << endl<< Text_Binary << endl;

    vector<bool> Text_Binary_Vector = str_64bit_2_vector(Text_Binary);


    vector<bool> Key_Binary_Vector = str_64bit_2_vector(Key_Binary);

    vector<bool> RES_Binary_Vector;

    RES_Binary_Vector = des_64bit(Text_Binary_Vector, Key_Binary_Vector, ENCRYPT);//加密

    cout << "加密后" << endl;
    Print(RES_Binary_Vector);

    vector<bool> DERES_Binary_Vector;

    Key_Binary_Vector = str_64bit_2_vector(Key_Binary);

    DERES_Binary_Vector = des_64bit(RES_Binary_Vector, Key_Binary_Vector, DECRYPT);
    
    cout << "解密后" << endl;
    Print(DERES_Binary_Vector);
    return 0;
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值