DES算法的C++代码

DES算法总体分成两步,第一步是根据给定的16位16进制数(64个二进制位)秘钥,按照一定的规则,产生16个子秘钥;第二步是对64位二进制信息单位进行加密。具体过程下面会逐步展示,为了叙述方便,本文将结合具体加密实例进行说明。
首先给出加密过程需要用到的参照表,这些参照表是加密算法提前给定的。笔者给定参照表具体如下列出。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述这里写图片描述

经过上述对DES算法每一步的深入研究分析,在理论上对DES算法的实现有了较为清晰的思路,笔者将依据上述理论分析,在Windows10操作系统下,利用Codeblocks开发环境,采用C++11标准对DES算法进行代码实现。
笔者特别说明,为了简便话,笔者使用随机数来生成算法所需的各个表格,并且在加密和解密过程中用到的密钥相同,参照表格相同。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
using namespace std;

char plaintext[8];//明文8字符,64位
char key[16];//秘钥,16个16进制数,64位
char ciphertext[16];//密文,16个16进制数,64位

int PC_1[8][7];//64位秘钥转成56位秘钥所用表
int left_move_table[16];//循环左移参照表
int PC_2[8][6];//cidi56位秘钥转成48位秘钥ki所用表
int E_bit_selection_table[8][6];//在f函数执行期间,转换Ri用到的参照表

int IP_1[8][8];//initial permutation ,64位数据第一次变换参照的表
int S[8][4][16];//8个S盒
int sub_key[17][48];//16个子秘钥,k1到k16
int P[8][4];//
int IP_2[8][8];//最后一次变换所参照的表
int L[17][32],R[17][32];//数据加密阶段,产生16对数据块1到16分别存放

void init();//初始化各个参照表
void hex_bin(char x,int tmp[]);//16进制数x转成4位二进制
void bin_hex(int tmp[4],char &c);//4位2进制转16进制,结果存放在字符c中
void char_to_bin(char c,int tmp[]);//把一个ADCII码字符转成2进制8位存储到tmp
void circle_left_move(int a[],int step);//循环左移,这里只有28位的秘钥,左移step位
void make_sub_key();//产生子秘钥

void exclusive_or(int a[],int b[],int n,int result[]);//异或,a数组,b数组表示的两个n位二进制数进行异或
void make_random(int n,int s[]);//产生n个随机数,放在数组a中

void f(int n,int P_end[32]);//得到的f存到P_end数组中
void des();//执行DES算法
void decode();//解密

void go();//程序控制

int main()
{
    go();
    return 0;
}

//产生n个互不相同的数分别是1-n
void make_random(int n,int s[]){
    int a[64];
    int index=0;
    for(int i=0;i<n;i++){
        a[i]=i+1;
    }
    srand(unsigned(time(0)));//播种子
    for(int i=0;i<n;){
        index=rand()%n;
        if(a[index]!=0){
            s[i]=a[index];
            a[index]=0;
            i++;
        }
    }
}

void init(){
    int s[64];//存放产生的随机数
    int cnt=0;
    //初始化PC_1表(64位秘钥转56位秘钥参照表)
    make_random(64,s);
    cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<7;j++){
            PC_1[i][j]=s[cnt++];
        }
    }

    //初始化循环左移表left_move_table
    for(int i=0;i<16;i++){
        left_move_table[i]=rand()%6+1;//这里假设循环左移1到6位
    }

    //初始化PC_2表(56位秘钥转48位秘钥参照表)
    make_random(48,s);
    cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<6;j++){
            PC_2[i][j]=s[cnt++];
        }
    }

    //初始化IP_1表(64位原始数据转成新的64位数据块
    make_random(64,s);
    cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            IP_1[i][j]=s[cnt++];
        }
    }

    //初始化E_bit_selection_table,在f函数执行期间对Ri转换下
    //32位扩到48位,只能在1-32选取
    for(int i=0;i<8;i++){
        for(int j=0;j<6;j++){
            E_bit_selection_table[i][j]=rand()%32+1;
        }
    }

    //初始化S盒
    for(int i=0;i<8;i++){
        for(int j=0;j<4;j++){
            make_random(16,s);
            cnt=0;
            for(int k=0;k<16;k++){
                s[k]-=1;
            }
            for(int k=0;k<16;k++){
                S[i][j][k]=s[cnt++];
            }
        }
    }

    //初始P,8个盒子已经搞完了一遍
    make_random(32,s);
    cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<4;j++){
            P[i][j]=s[cnt++];
        }
    }

    //初始化最后一个表IP_2
    make_random(64,s);
    cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            IP_2[i][j]=s[cnt++];
        }
    }
}

//一个十六进制数转成4位二进制数
void hex_bin(char x,int tmp[]){
    int a,b,c,d;
    if('0'==x){a=0;b=0;c=0;d=0;}
    else if('1'==x){a=0;b=0;c=0;d=1;}
    else if('2'==x){a=0;b=0;c=1;d=0;}
    else if('3'==x){a=0;b=0;c=1;d=1;}
    else if('4'==x){a=0;b=1;c=0;d=0;}
    else if('5'==x){a=0;b=1;c=0;d=1;}
    else if('6'==x){a=0;b=1;c=1;d=0;}
    else if('7'==x){a=0;b=1;c=1;d=1;}
    else if('8'==x){a=1;b=0;c=0;d=0;}
    else if('9'==x){a=1;b=0;c=0;d=1;}
    else if('a'==x || 'A'==x){a=1;b=0;c=1;d=0;}
    else if('b'==x || 'B'==x){a=1;b=0;c=1;d=1;}
    else if('c'==x || 'C'==x){a=1;b=1;c=0;d=0;}
    else if('d'==x || 'D'==x){a=1;b=1;c=0;d=1;}
    else if('e'==x || 'E'==x){a=1;b=1;c=1;d=0;}
    else if('f'==x || 'F'==x){a=1;b=1;c=1;d=1;}
    tmp[0]=a;tmp[1]=b;tmp[2]=c;tmp[3]=d;
}

void bin_hex(int tmp[4],char &c){
    int sum=tmp[0]*8+tmp[1]*4+tmp[2]*2+tmp[3]*1;
    if(sum>=0 && sum<=9){
        c=sum+'0';
    }
    else{
        if(10==sum) c='a';
        else if(11==sum) c='b';
        else if(12==sum) c='c';
        else if(13==sum) c='d';
        else if(14==sum) c='e';
        else if(15==sum) c='f';
    }

}

//一个字符转成8位二进制数
void char_to_bin(char c,int tmp[]){
    int n=(int)c;//把ASCII码字符强制转为整数
    int cnt=7;
    while(n/2){
        tmp[cnt--]=n%2;
        n/=2;
    }
    tmp[cnt]=n;
    for(int i=0;i<cnt;i++){
        tmp[i]=0;
    }
}

//一个数转成4位的二进制数
void number_to_bin(int n,int tmp[]){
    int cnt=3;
    while(n/2){
        tmp[cnt--]=n%2;
        n/=2;
    }
    tmp[cnt]=n;
    for(int i=0;i<cnt;i++){
        tmp[i]=0;
    }
}

void circle_left_move(int a[],int step){
    int tmp[28];
    int cnt=0;
    for(int i=step-1;i<28;i++){
        tmp[cnt++]=a[i];
    }
    for(int i=0;i<step;i++){
        tmp[cnt++]=a[i];
    }
    for(int i=0;i<28;i++){
        a[i]=tmp[i];
    }
}

void make_sub_key(){
    int kkey[64];//把16个16进制的数搞成64个二进制的数,并存储在kkey数组中
    int kkey_cnt=0;
    //秘钥key中的16个16进制数搞成二进制数共64位存到kkey数组中
    for(int i=0;i<16;i++){
        int tmp[4];
        hex_bin(key[i],tmp);
        for(int j=0;j<4;j++){
            kkey[kkey_cnt++]=tmp[j];
        }
    }

    int K[56];//原秘钥64位搞成56位放在K里面
    int K_cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<7;j++){
            K[K_cnt++]=kkey[PC_1[i][j]-1];//参照表PC_1来搞,把64位搞成56位秘钥
        }
    }
    int c[17][28],d[17][28];
    //64位秘钥搞成56位秘钥后,拆成两半,分别给c[0]和d[0]
    for(int i=0;i<28;i++){
        c[0][i]=K[i];
        d[0][i]=K[i+28];
    }

    //循环左移16次,得到16对ci,di,存到c[17][28],d[17][28]
    for(int i=0;i<16;i++){
        int tmp_c[28],tmp_d[28];//暂时存储c[i]和d[i]
        for(int j=0;j<28;j++){
            tmp_c[j]=c[i][j];
            tmp_d[j]=d[i][j];
        }
        //c[i],d[i]都循环左移left_move_table[i]位
        circle_left_move(tmp_c,left_move_table[i]);
        circle_left_move(tmp_d,left_move_table[i]);
        //c[i],d[i]循环左移后,就变成了c[i+1],d[i+1]
        for(int j=0;j<28;j++){
            c[i+1][j]=tmp_c[j];
            d[i+1][j]=tmp_d[j];
        }
    }

    //对16对cidi56位秘钥用PC_2表转成48位秘钥,存到sub_key数组中
    for(int i=0;i<16;i++){
        int tmp[56];//暂存c[i+1],d[i+1]组成56位秘钥
        for(int j=0;j<28;j++){
            tmp[j]=c[i+1][j];
            tmp[j+28]=d[i+1][j];
        }

        //56位转成48位
        int cnt=0;
        for(int j=0;j<8;j++){
            for(int k=0;k<6;k++){
                sub_key[i+1][cnt++]=tmp[PC_2[j][k]-1];
            }
        }
    }
}

void exclusive_or(int a[],int b[],int n,int result[]){
    for(int i=0;i<n;i++){
        if(a[i]==b[i]){
            result[i]=0;
        }
        else{
            result[i]=1;
        }
    }
}


void f(int n,int P_end[32]){
    int E[48];
    int E_cnt=0;
    //Ri通过E_bit_selection_table表转换一下,存到E中
    for(int i=0;i<8;i++){
        for(int j=0;j<6;j++){
            E[E_cnt++]=R[n-1][E_bit_selection_table[i][j]-1];
        }
    }
    int tmp_sub_key[48];//暂存sub_key[n],一维数组便于操作
    for(int i=0;i<48;i++){
        tmp_sub_key[i]=sub_key[n][i];
    }

    int exclusive_or_result[100];//存放异或结果的数组
    exclusive_or(E,tmp_sub_key,48,exclusive_or_result);

    //把子秘钥sub_key[i]与E异或后的结果exclusive_or_result,48位拆成8份
    //每一份有6位,分别对每一份进行S盒转变
    int temp_result[8][6];
    int temp_result_cnt=0;
    for(int i=0;i<48;i++){
        if(i%6==0 && i!=0){
            temp_result_cnt++;
        }
        temp_result[temp_result_cnt][i%6]=exclusive_or_result[i];
    }

    int row;//是S盒中对应的行
    int col;//在S盒中对于的列
    int S8_end[32];//8个盒搞完之后的结果
    int S8_end_cnt=0;//8个S盒过一遍之后的结果计数
    for(int i=0;i<8;i++){
        row=temp_result[i][0]*2+temp_result[i][5]*1;
        col=temp_result[i][1]*8+temp_result[i][2]*4+temp_result[i][3]*2+temp_result[i][4]*1;
        int tmp[4];//每一份6位变成4位后暂存tmp数组中
        int number=S[i][row][col];//S盒中对应的那个数
        number_to_bin(number,tmp);//S盒中对应的那个数转成二进制,暂存在tmp数组
        for(int j=0;j<4;j++){
            S8_end[S8_end_cnt++]=tmp[j];
        }
    }
    //8个盒子过一遍之后,经P再搞一下,存到P_end里面,即f

    int P_cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<4;j++){
            P_end[P_cnt++]=S8_end[P[i][j]-1];
        }
    }
}

void des(){
    int M[64];
    int M_cnt=0;
    //先把8个字符转成64位2进制数,存到M数组中
    for(int i=0;i<8;i++){
        int tmp[8];//存储每一个1字符对应的8位二进制
        char_to_bin(plaintext[i],tmp);
        for(int j=0;j<8;j++){
            M[M_cnt++]=tmp[j];
        }
    }
    int IP[64];//拿到8字符,转成64位二进制数据块后,安装IP_1表搞一下,搞成新的64位,存到IP数组中
    int IP_cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            IP[IP_cnt++]=M[IP_1[i][j]-1];
        }
    }
    //初始化L[0],R[0]为后续f函数准备
    for(int i=0;i<32;i++){
        L[0][i]=IP[i];
        R[0][i]=IP[i+32];
    }

    //根据Ln=Rn-1,Rn=Ln-1+f(Rn-1,Kn)公式迭代,这里笔者对此公式更加简化如下
    //Ln=Rn-1,Rn=f(n-1)
    //下面16次循环后,可以求出L16,R16
    for(int i=1;i<=16;i++){
        for(int j=0;j<32;j++){
            L[i][j]=R[i-1][j];//Ln=Rn-1
        }
        int P_end[32];
        f(i,P_end);//Rn=f(n)+Ln-1,这里求出了f,下面异或下产生Rn

        int L_tmp[32];
        for(int j=0;j<32;j++){
            L_tmp[j]=L[i-1][j];//这里开始还是写错了L_tmp[j]的j写成了i,这一点导致了极大的错误,加密和解密求的f全然不同,导致所有的L,R都不同
        }

        exclusive_or(P_end,L_tmp,32,P_end);
        //上面异或的结果就是Rn
        for(int j=0;j<32;j++){
            R[i][j]=P_end[j];
        }//至此,由f(n-1)终于求出了Rn
    }
    //求出的R16L16暂存在R16L16的数组中
    int R16L16[64];
    for(int i=0;i<32;i++){
        R16L16[i]=R[16][i];
        R16L16[i+32]=L[16][i];
    }

    int goal[64];//R16L16再过一遍IP_2
    int goal_cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            goal[goal_cnt++]=R16L16[IP_2[i][j]-1];
        }
    }

    //把得到的64位二进制转成16个16进制数
    int tmp_goal[4];
    char c;
    int ciphertext_cnt=0;
    for(int i=0;i<64;i++){
        tmp_goal[i%4]=goal[i];
        if((i+1)%4==0){
            bin_hex(tmp_goal,c);
            ciphertext[ciphertext_cnt++]=c;
        }
    }
}

//对加密之后的密文解密
void decode(){
    //61个16进制数的密文先搞成64位,存到tmp1

    int tmp1[64];
    int tmp1_cnt=0;
    for(int i=0;i<16;i++){
        int tmp[4];//把一个16进制数转成4位的二进制数,存到tmp中
        hex_bin(ciphertext[i],tmp);
        for(int j=0;j<4;j++){
            tmp1[tmp1_cnt++]=tmp[j];
        }
    }

    //继续解密,先搞出R16L16
    tmp1_cnt=0;
    int R16L16[64];
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            R16L16[IP_2[i][j]-1]=tmp1[tmp1_cnt++];
        }
    }

    //为了不定义更多的变量,下面求解过程中依然用加密过程中用到的变量
    for(int i=0;i<32;i++){
        R[16][i]=R16L16[i];
        L[16][i]=R16L16[i+32];
    }

    //经过16次f函数迭代,求L0,R0
    for(int i=16;i>=1;i--){
        for(int j=0;j<32;j++){
            R[i-1][j]=L[i][j];
        }


        int P_end[32];
        f(i,P_end);
        int R_tmp[32];
        for(int j=0;j<32;j++){
            R_tmp[j]=R[i][j];
        }
        exclusive_or(R_tmp,P_end,32,P_end);
        for(int j=0;j<32;j++){
            L[i-1][j]=P_end[j];
        }

    }
    int L0R0[64];
    for(int i=0;i<32;i++){
        L0R0[i]=L[0][i];
        L0R0[i+32]=R[0][i];
    }

    //求出起初的明文64位二进制表示,存到M数组
    int M[64];//
    int L0R0_cnt=0;
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            M[IP_1[i][j]-1]=L0R0[L0R0_cnt++];//这里有问题,看看!!!!!!!!!!!!!!!!!!!!!!!!
        }
    }

    //把64位的M转成8个字符,并输出明文
    int tmp_last[8][8];
    int tmp_last_cnt=0;
    //64位拆成8等份
    for(int i=0;i<64;i++){
        if(i%8==0 && i!=0){
            tmp_last_cnt++;
        }
        tmp_last[tmp_last_cnt][i%8]=M[i];
    }

    int mark[8]={128,64,32,16,8,4,2,1};
    for(int i=0;i<8;i++){
        int x=0;
        for(int j=0;j<8;j++){
            x+=mark[j]*tmp_last[i][j];
        }
        plaintext[i]=(char)x;
    }
}


void go(){
    FILE *fp_plaintext;
    FILE *fp_ciphertext;
    FILE *fp_decode_text;
    FILE *fp_key;

    fp_plaintext=fopen("plaintext.txt","r");
    fp_ciphertext=fopen("ciphertext.txt","w");
    fp_decode_text=fopen("decode_text.txt","w");
    fp_key=fopen("key.txt","r");

    char c;
    init();
    int key_cnt=0;
    while((c=fgetc(fp_key))!=EOF){
        key[key_cnt++]=c;
    }
    make_sub_key();


    int cnt=0;
    int sum=0;
    while((c=fgetc(fp_plaintext))!=EOF){
        plaintext[cnt%8]=c;
        cnt++;
        sum++;
        if(cnt%8==0 && cnt!=0 && sum==8){
            des();
            for(int i=0;i<8;i++){
                fputc(ciphertext[i],fp_ciphertext);
            }
            decode();//解密
            for(int i=0;i<8;i++){
                fputc(plaintext[i],fp_decode_text);
            }
            sum=0;
        }
    }
    if(sum!=0){
        for(int i=sum;i<8;i++){
            plaintext[i]='0';//不够8位填充0
        }
        des();
        for(int i=0;i<8;i++){
            fputc(ciphertext[i],fp_ciphertext);
        }
        decode();//解密
        for(int i=0;i<8;i++){
            fputc(plaintext[i],fp_decode_text);
        }
    }
    fclose(fp_plaintext);
    fclose(fp_ciphertext);
    fclose(fp_decode_text);
    fclose(fp_key);
}

4 实验测试
笔者将使用上述代码进行实验测试。使用文件读写方式,plaintext.txt文件存放待加密的数据,ciphertext.txt文件存放加密好的数据,key.txt文件存放1616进制数组成的秘钥,decode_text.txt文件存放经加密再解密的数据。由于本算法实现过程中,加密解密用到的参照表及秘钥完全一样,可以通过对比plaintext.txt文件和decode_text.txt文件内容,如果一致,可以在一定程度上说明算法的正确性。
(1)plaintext.txt文件中的待加密数据如下:
I am a student from CCNU.
I love coding!
Hello, Wolrd!
!!!!!!!!!
(2)key.txt文件中的秘钥如下:
1234569870abcdef
(3)程序运行之后,ciphertext.txt文件中的数据如下:
5ff508a138d8a0f826ae29f6c9b80ad4fefdebf88062bd1574f648693a63c2e5
(4)程序运行之后,decode_text.txt文件内容如下:
I am a student from CCNU.
I love coding!
Hello, Wolrd!
!!!!!!!!!
对比plaintext.txt文件和decode_text.txt文件内容,完全一致,这表明原始数据和加密后再解密的数据一致,可以在一定程度上说明算法的正确性。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DES(Data Encryption Standard)算法是最早的加密标准之一,使用对称密钥加密方法,对数据进行加密以保障数据的机密性、完整性和可用性。C语言可以通过各种方式实现DES算法,这里简要介绍一种常见的实现方法。 首先,需要引入相关的头文件,包括"stdio.h"、"stdlib.h"、"string.h"等。 接下来,需要定义一些常量,如密钥长度、子密钥轮数等。同时,需要定义一些结构体和数组,如: - DESSubKey:存储子密钥的结构体 - IP:初始置换矩阵 - IPInv:初始置换的逆矩阵 - E:扩展矩阵 - S:S盒 - P:P盒 然后,需要实现一些函数,如: - IPPerm:实现初始置换 - IPInvPerm:实现初始置换的逆置换 - ExtendPerm:实现扩展置换 - SBoxPerm:实现S盒置换 - PBoxPerm:实现P盒置换 - KeySchedule:生成子密钥 - DESRound:DES算法轮加密操作 最后,可以实现一个DES加密函数,接收一个明文和一个密钥,返回加密后的密文。该函数主要包括以下步骤: - 检查明文和密钥长度是否符合要求 - 生成子密钥 - 进行初始置换 - 进行16轮加密 - 进行末置换 以上是一种常见的DES算法实现方法,但由于DES算法已经不再安全,建议使用更为安全的加密算法,如AES(Advanced Encryption Standard)。 ### 回答2: DES(Data Encryption Standard)是一种对称加密算法,它使用同一个密钥进行加密和解密,密钥长度为56位。下面是在C语言中实现DES算法代码: 首先需要引入DES算法头文件#include "..\..\crypto\des\des.h" 定义DES算法所需的变量:char key[8]; //8字节密钥 unsigned char plaintext[8]; //明文 unsigned char ciphertext[8]; //密文 接下来,使用DES_set_key函数来设置密钥: DES_cblock key32; //key32用于存储56位密钥转换后的64位密钥 unsigned char key[8]; //输入的8字节密钥 memcpy(key, "12345678", 8); //设置密钥的值 memset(key32, 0, 8); //初始化64位密钥 DES_set_key_checked(&key, &key32); //将8字节密钥转换成64位密钥并设置为DES算法的密钥 然后,使用DES_ecb_encrypt函数对明文进行加密: DES_cblock input32; //input32用于存储8字节明文转换后的64位明文 DES_cblock output32; //output32用于存储8字节密文 memset(input32, 0, 8); //初始化64位明文 memcpy(input32, plaintext, 8); //设置明文的值 DES_ecb_encrypt(&input32, &output32, &key32, DES_ENCRYPT); //对明文进行加密 最后,使用DES_ecb_encrypt函数对密文进行解密: DES_cblock input32; //input32用于存储8字节密文转换后的64位密文 DES_cblock output32; //output32用于存储8字节明文 memset(input32, 0, 8); //初始化64位密文 memcpy(input32, ciphertext, 8); //设置密文的值 DES_ecb_encrypt(&input32, &output32, &key32, DES_DECRYPT); //对密文进行解密 通过以上代码,我们就可以在C语言中实现DES算法的加密和解密功能。 ### 回答3: DES算法是对称加密算法中的一种,它使用固定长度的密钥将数据块转换为加密数据块。该算法由IBM研发,在1977年被NSA标准化,成为一种广受使用的加密标准。在实现DES算法时,需要用到C语言进行编程。 在实现DES算法时,需要使用多个函数来完成加密和解密的过程。首先,需要定义几个常量,以及一些用于加密和解密的函数。这些函数包括: 1. IP置换函数(Initial Permutation),用于对64位明文按照规定的顺序重新排列。 2. F函数,用于对32位数据进行压缩和扩展,以及与子密钥进行异或操作和替换操作。 3. PC1函数和PC2函数,分别用于从64位密钥中生成56位子密钥。 4. E置换函数(Expansion Permutation),用于将32位数据扩展为48位数据。 5. P置换函数(Permutation),用于对32位数据按照规定的顺序进行重新排列。 在进行加密和解密的过程中,需要使用的主要函数包括: 1. KeySchedule函数,用于生成16个48位子密钥。 2. DES_Encrypt函数和DES_Decrypt函数,用于分别进行加密和解密的操作。 在具体实现DES算法时,需要参考DES标准的具体实现方式和协议。同时,还需要考虑到实现过程中可能出现的安全漏洞和攻击手段,以及如何进行防御和修补。因此,在进行DES算法的实现时,需要认真学习和理解相关的知识,才能够编写出安全可靠的加密算法代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值