21xrx.com
2024-09-17 04:29:53 Tuesday
登录
文章检索 我的文章 写文章
DES算法C++实现
2023-07-09 15:29:56 深夜i     --     --
DES算法 C++ 实现 加密 解密

DES算法是一种高级加密标准,被广泛应用于数据加密领域。在数据传输、数据存储以及身份验证等领域中,都需要使用加密算法来保障数据的安全。本文将介绍DES算法的C++实现,让读者了解其用法和实现过程。

1. DES算法简介

DES算法全称是数据加密标准(Data Encryption Standard),它是美国联邦政府所采用的一种数据加密标准。DES算法采用的是对称加密的方法,即加密和解密使用同样的密钥。DES算法的工作流程包括:初始置换、16轮加密、逆置换三个过程。其中,初始置换和逆置换是位置换的过程,16轮加密是使用不同的密钥形成的轮换密钥对数据进行加密的过程。

2. C++实现

以下是DES算法的C++实现代码:

#include

#include

#include

#include

#include

#include

using namespace std;

//定义初始置换表

int ip[] = 60;

//定义逆置换表

int ipt[] = 9;

//定义扩展表

int ept[] = 18;

//定义置换函数表

int pt[] = 23;

//定义S盒表,共8个S盒,每个S盒包含4行16列

int sBox[8][4][16] = {

    // S1

    {

         3,

         9,

         9,

         3

    },

    // S2

    {

         14,

         5,

         7,

         7

    },

    // S3

    {

         1,

         5,

         6,

         7

    },

    // S4

    {

         0,

         5,

        10,

         9

    },

    // S5

    {

         9,

         12,

         13,

         13

    },

    // S6

    {

        12,

        10,

         12,

         2

    },

    // S7

    {

         12,

         5,

         7,

         11

    },

    // S8

    {

         14,

         13,

         9,

         15

    }

};

//左移位数表,共16次

int leftMove[] = 2;

//十六进制转二进制

string hexToBin(string hex){

  string bin = "";

  for (int i = 0; i < hex.length(); i++){

    if (hex[i] >= '0' && hex[i] <= '9'){

      bin += bitset<4>(hex[i] - '0').to_string();

    }else{

      bin += bitset<4>(hex[i] - 'A' + 10).to_string();

    }

  }

  return bin;

}

//二进制转十六进制

string binToHex(string bin){

  string hex = "";

  for (int i = 0; i < bin.length(); i += 4){

    hex += bitset<4>(bin.substr(i, 4)).to_ulong() < 10 ?

    to_string(bitset<4>(bin.substr(i, 4)).to_ulong()) :

    string(1, 'A' + bitset<4>(bin.substr(i, 4)).to_ulong() - 10);

  }

  return hex;

}

//异或函数

string xorStr(string a, string b){

  string res = "";

  for (int i = 0; i < a.length(); i++){

    res += a[i] ^ b[i];

  }

  return res;

}

//补齐函数,长度不足8的倍数,左边补充0

string padding(string plain){

  while (plain.length() % 8 != 0){

   plain = "0" + plain;

  }

  return plain;

}

//生成子密钥

vector getKeys(string key){

  vector keys(16);

  //转成二进制

  string binKey = hexToBin(key);

  //密钥置换1

  int pc1[] = 47;

  string key1 = "";

  for (int i = 0; i < 56; i++){

    key1 += binKey[pc1[i] - 1];

  }

  //16轮循环生成子密钥

  string leftKey = key1.substr(0, 28);

  string rightKey = key1.substr(28);

  for (int i = 0; i < 16; i++){

    //左移

    leftKey = leftKey.substr(leftMove[i]) + leftKey.substr(0, leftMove[i]);

    rightKey = rightKey.substr(leftMove[i]) + rightKey.substr(0, leftMove[i]);

    //密钥置换2

    int pc2[] = 21;

    string key2 = leftKey + rightKey;

    string subKey = "";

    for (int j = 0; j < 48; j++){

      subKey += key2[pc2[j] - 1];

    }

    keys[i] = subKey;

  }

  return keys;

}

//f函数

string f(string right, string subKey){

  //扩展置换

  string expR = "";

  for (int i = 0; i < 48; i++){

    expR += right[ept[i] - 1];

  }

  //与子密钥异或

  expR = xorStr(expR, subKey);

  //分为八个6位分组

  string sPlain[8];

  for (int i = 0; i < 8; i++){

    sPlain[i] = expR.substr(i * 6, 6);

  }

  //处理八个S盒

  string sResult = "";

  for (int i = 0; i < 8; i++){

    //处理第i个S盒

    int row = bitset<2>(sPlain[i].substr(0, 1) + sPlain[i].substr(5)).to_ulong();

    int col = bitset<4>(sPlain[i].substr(1, 4)).to_ulong();

    int num = sBox[i][row][col];

    sResult += bitset<4>(num).to_string();

  }

  // P置换

  string pResult = "";

  for (int i = 0; i < 32; i++){

    pResult += sResult[pt[i] - 1];

  }

  return pResult;

}

//加密

string encrypt(string plain, string key){

  //补齐

  plain = padding(plain);

  //生成子密钥

  vector keys = getKeys(key);

  //初始置换

  string binPlain = hexToBin(plain);

  string ipResult = "";

  for (int i = 0; i < 64; i++){

    ipResult += binPlain[ip[i] - 1];

  }

  //分为左右两部分

  string left = ipResult.substr(0, 32);

  string right = ipResult.substr(32);

  // 16轮

  for (int i = 0; i < 16; i++){

    string temp = left;

    //右边进行f函数操作,然后与左边异或

    left = right;

    right = xorStr(temp, f(right, keys[i]));

  }

  //重新组合为64位

  string preC = right + left;

  //逆置换

  string cipher = "";

  for (int i = 0; i < 64; i++){

    cipher += preC[ipt[i] - 1];

  }

  //返回密文

  return binToHex(cipher);

}

//解密

string decrypt(string cipher, string key){

  //生成子密钥

  vector keys = getKeys(key);

  //初始置换

  string binCipher = hexToBin(cipher);

  string ipResult = "";

  for (int i = 0; i < 64; i++){

    ipResult += binCipher[ip[i] - 1];

  }

  // 分为左右两部分

  string left = ipResult.substr(0, 32);

  string right = ipResult.substr(32);

  // 16轮

  for (int i = 15

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复