DES加解密

C代码

#include<iostream>
#include <string>
#include <cstring> // 添加memset函数需要的头文件
using namespace std;

#include<iostream>
#include <string>
using namespace std;
static bool M[64], tmp[32], *Li = &M[0], *Ri = &M[32];
static bool SubKey[16][48];//16个子密钥
const static char IP[64] =//初始置换
{
	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
};
const static char EP1[56] =//密钥置换选择1(原64位去掉奇偶校验位后)
{
	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
};

const static char LOOP[16] =//左移
{
	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};

const static char EP2[48] =//置换选择2
{
	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
};

static const char EC[48] =//E盒扩展表
{
  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
};


const static char SBox[8][4][16] =//8个S盒
{
      {
		// 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   }
	  }
};

const static char PP[32] =//P盒置换
{
	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,
};

const static char LP[64] =//初始逆置换
{
	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
};

void ByteToBit(bool *Out, const char *In, int bits)//字符转换成bit
{
	int i;
	for (i = 0; i < bits; i++)
	{
		// In[i]的第N位右移N位并和0x01按位"与"运算(N=1~8)
		Out[i] = (In[i / 8] >> (i % 8)) & 1;
	}
}
void BitToByte(char *Out, const bool *In, int bits)//bit转换成字符
{
	int i;
	memset(Out, 0, (bits + 7) / 8);
	for (i = 0; i < bits; i++)
	{
		Out[i / 8] |= In[i] << (i % 8);
	}
}
void BitToHex(char *Out, const bool *In, int bits)//二进制转换成十六进制
{
	int i;
	for (i = 0; i < bits/ 4; i++)
	{
		Out[i] = 0;
	}
	for (i = 0; i <bits/4; i++)
	{
		Out[i] = In[4 * i] + In[4 * i + 1] * 2 + In[4 * i + 2] * 4 + In[4 * i + 3] * 8;
		if (Out[i] % 16 > 9)
		{
			Out[i] = Out[i]%16 + '7';
		}
		else
			Out[i] = Out[i]%16 + '0';
	}
}
void HexToBit( bool *Out, char *In, int bits)//十六进制转换成二进制
{
	 int i;
	 for (i = 0; i < bits; i++)
	 {
		if (In[i/4] <= '9')
	     {
			 Out[i] = ((In[i / 4] - '0') >> (i % 4)) & 0x01;
	     }
		  else
		  {
			 Out[i] = ((In[i / 4] - '7') >> (i % 4)) & 0x01;
		  }
	}
}
void RotateL(bool*In, int len, int loop)//循环左移
{
	static bool tmp[256];
	memcpy(tmp, In, loop);
	memcpy(In, In + loop, len - loop);
	memcpy(In + len - loop, tmp, loop);
}
void Xor(bool*InA, const bool*InB, int len)//异或
{
	int i;
	for (i = 0; i < len; i++)
	{
		InA[i] ^= InB[i];
	}
}
void Transform(bool*Out, bool*In, const char*Table, int len)//各个置换转换
{
	int i;
	static bool tmp[256];
	for (i = 0; i < len; i++)
	{
		tmp[i] = In[Table[i] - 1];
	}
	memcpy(Out, tmp, len);
}
void S_func(bool Out[32], const bool In[48])//S盒压缩处理
{
	int j, m, n;
	//膨胀后的比特串分为8组,每组6比特。 
	for (j = 0; j < 8; j++, In += 6, Out += 4)
	{
		m = (In[0] * 2) + In[5];
		n = (In[1] * 8) + (In[2] * 4) + (In[3] * 2) + In[4];
		ByteToBit(Out, &SBox[j][m][n], 4);
	}
}
void F_func(bool In[32], const bool Ki[48])//轮函数运算
{
	static bool MR[48];
	Transform(MR, In, EC, 48);
	Xor(MR, Ki, 48);
	//膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特,合并后又成为32比特。
	S_func(In, MR);
	//该32比特经过P变换后,输出的比特串才是32比特的f(Ri-1,Ki)。
	Transform(In, In, PP, 32);
}
void SetKey(char key[8]) //生成子密钥
{
    static bool K[64], *KL = &K[0], *KR = &K[28];
    ByteToBit(K, key, 64);
    
    // 置换选择1 (PC-1)
    static bool PK[56];
    Transform(PK, K, EP1, 56);
    
    // 分为左右两部分 C0 和 D0
    bool C[28], D[28];
    memcpy(C, PK, 28);
    memcpy(D, PK+28, 28);
    
    for(int i=0; i<16; i++) {
        // 循环左移
        RotateL(C, 28, LOOP[i]);
        RotateL(D, 28, LOOP[i]);
        
        // 合并后置换选择2 (PC-2)
        bool CD[56];
        memcpy(CD, C, 28);
        memcpy(CD+28, D, 28);
        Transform(SubKey[i], CD, EP2, 48);
    }
}

void Run_Des(char In[8], char out[16]) //加密函数
{
    // 初始置换IP
    ByteToBit(M, In, 64);
    Transform(M, M, IP, 64);
    
    // 分为L0和R0
    bool *L = Li, *R = Ri;
    
    // 16轮Feistel变换
    for(int i=0; i<16; i++) {
        memcpy(tmp, R, 32); // tmp = R[i-1]
        
        // F函数
        F_func(R, SubKey[i]);
        Xor(R, L, 32);     // R[i] = L[i-1] XOR F(R[i-1], K[i])
        
        memcpy(L, tmp, 32); // L[i] = R[i-1]
    }
    
    // 最后交换左右并逆初始置换
    bool RL[64];
    memcpy(RL, R, 32);
    memcpy(RL+32, L, 32);
    Transform(M, RL, LP, 64);
    
    // 转换为16进制输出
    BitToHex(out, M, 64);
}

void Run_desDes(char out[8], char In[16]) //解密函数
{
    // 16进制转二进制
    HexToBit(M, In, 64);
    
    // 初始置换IP
    Transform(M, M, IP, 64);
    
    // 分为L0和R0
    bool *L = Li, *R = Ri;
    
    // 16轮Feistel变换(子密钥逆序使用)
    for(int i=0; i<16; i++) {
        memcpy(tmp, R, 32); // tmp = R[i-1]
        
        // F函数
        F_func(R, SubKey[15-i]);
        Xor(R, L, 32);     // R[i] = L[i-1] XOR F(R[i-1], K[16-i])
        
        memcpy(L, tmp, 32); // L[i] = R[i-1]
    }
    
    // 最后交换左右并逆初始置换
    bool RL[64];
    memcpy(RL, R, 32);
    memcpy(RL+32, L, 32);
    Transform(M, RL, LP, 64);
    
    // 转换为字节输出
    BitToByte(out, M, 64);
}

int main() {
    char plaintext[8] = {0};
    char key[8] = {0};
    char ciphertext[16] = {0};
    char decrypted[8] = {0};
    
    // 输入处理
    cout << "请输入姓名拼音缩写: ";
    string input;
    cin >> input;
    
    // 确保明文为8字节,不足补0
    strncpy(plaintext, input.c_str(), 8);
    plaintext[8] = '\0';
    
    cout << "请输入密钥: ";
    string keyInput;
    cin >> keyInput;
    
    // 确保密钥为8字节
    if(keyInput.length() != 8) {
        cout << "密钥必须为8位数字!" << endl;
        return 1;
    }
    strncpy(key, keyInput.c_str(), 8);
    
    // 生成子密钥
    SetKey(key);
    
    // 加密
    Run_Des(plaintext, ciphertext);
    cout << "\n加密结果(16进制): ";
    for(int i=0; i<16; i++) {
        cout << ciphertext[i];
    }
    cout << endl;
    
    // 解密
    Run_desDes(decrypted, ciphertext);
    cout << "解密结果: ";
    for(int i=0; i<8 && decrypted[i] != '\0'; i++) {
        cout << decrypted[i];
    }
    cout << endl;
    
    // 验证
    if(strncmp(plaintext, decrypted, 8) == 0) {
        cout << "加解密验证成功!" << endl;
    } else {
        cout << "加解密验证失败!" << endl;
    }
    
    return 0;
}

py

import struct

# 初始置换表
IP = [
    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
]

# 密钥置换选择1
PC1 = [
    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
]

# 循环左移位数
SHIFT = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]

# 密钥置换选择2
PC2 = [
    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
]

# 扩展置换表
E = [
    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
]

# S盒
SBOX = [
    [
        [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]
    ],
    [
        [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]
    ],
    [
        [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]
    ],
    [
        [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]
    ],
    [
        [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]
    ],
    [
        [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]
    ],
    [
        [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]
    ],
    [
        [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]
    ]
]

# P盒置换
P = [
    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
]

# 逆初始置换
IP_INV = [
    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
]


def str_to_bitarray(s):
    """将字符串转换为位数组"""
    arr = []
    for c in s:
        bits = bin(ord(c))[2:].rjust(8, '0')
        arr.extend([int(b) for b in bits])
    return arr


def bitarray_to_str(arr):
    """将位数组转换为字符串"""
    s = ''
    for i in range(0, len(arr), 8):
        byte = arr[i:i + 8]
        s += chr(int(''.join(map(str, byte)), 2))
    return s


def hex_to_bitarray(h):
    """将十六进制字符串转换为位数组"""
    arr = []
    for c in h:
        bits = bin(int(c, 16))[2:].rjust(4, '0')
        arr.extend([int(b) for b in bits])
    return arr


def bitarray_to_hex(arr):
    """将位数组转换为十六进制字符串"""
    s = ''
    for i in range(0, len(arr), 4):
        nibble = arr[i:i + 4]
        s += hex(int(''.join(map(str, nibble)), 2))[2:]
    return s


def permute(block, table):
    """根据指定的置换表进行置换"""
    return [block[x - 1] for x in table]


def left_shift(arr, n):
    """循环左移"""
    return arr[n:] + arr[:n]


def generate_subkeys(key):
    """生成16个子密钥"""
    # 将密钥转换为位数组
    key_bits = str_to_bitarray(key)

    # PC1置换
    key_pc1 = permute(key_bits, PC1)

    # 分成左右两部分
    left = key_pc1[:28]
    right = key_pc1[28:]

    subkeys = []
    for i in range(16):
        # 循环左移
        left = left_shift(left, SHIFT[i])
        right = left_shift(right, SHIFT[i])

        # 合并后PC2置换
        combined = left + right
        subkey = permute(combined, PC2)
        subkeys.append(subkey)

    return subkeys


def f_function(r, subkey):
    """F函数"""
    # 扩展置换
    r_expanded = permute(r, E)

    # 与子密钥异或
    xor_result = [r_expanded[i] ^ subkey[i] for i in range(48)]

    # S盒替换
    sbox_result = []
    for i in range(8):
        block = xor_result[i * 6:(i + 1) * 6]
        row = (block[0] << 1) + block[5]
        col = (block[1] << 3) + (block[2] << 2) + (block[3] << 1) + block[4]
        val = SBOX[i][row][col]
        sbox_result.extend([(val >> 3) & 1, (val >> 2) & 1, (val >> 1) & 1, val & 1])

    # P盒置换
    return permute(sbox_result, P)


def des_encrypt(block, subkeys):
    """DES加密一个64位块"""
    # 初始置换
    block_bits = str_to_bitarray(block)
    block_ip = permute(block_bits, IP)

    # 分成左右两部分
    left = block_ip[:32]
    right = block_ip[32:]

    # 16轮Feistel变换
    for i in range(16):
        new_left = right
        new_right = [left[j] ^ f_function(right, subkeys[i])[j] for j in range(32)]
        left, right = new_left, new_right

    # 最后交换左右并逆初始置换
    combined = right + left
    cipher_bits = permute(combined, IP_INV)

    # 转换为16进制字符串
    return bitarray_to_hex(cipher_bits)


def des_decrypt(block, subkeys):
    """DES解密一个64位块"""
    # 16进制转位数组
    block_bits = hex_to_bitarray(block)

    # 初始置换
    block_ip = permute(block_bits, IP)

    # 分成左右两部分
    left = block_ip[:32]
    right = block_ip[32:]

    # 16轮Feistel变换(子密钥逆序使用)
    for i in range(15, -1, -1):
        new_left = right
        new_right = [left[j] ^ f_function(right, subkeys[i])[j] for j in range(32)]
        left, right = new_left, new_right

    # 最后交换左右并逆初始置换
    combined = right + left
    plain_bits = permute(combined, IP_INV)

    # 转换为字符串
    return bitarray_to_str(plain_bits)


def pad_text(text):
    """填充文本使其长度为8的倍数"""
    pad_len = 8 - (len(text) % 8)
    return text + chr(pad_len) * pad_len


def unpad_text(text):
    """去除填充"""
    pad_len = ord(text[-1])
    return text[:-pad_len]


def des_encrypt_text(text, key):
    """加密文本"""
    # 生成子密钥
    subkeys = generate_subkeys(key)

    # 填充文本
    padded_text = pad_text(text)

    # 分块加密
    ciphertext = ''
    for i in range(0, len(padded_text), 8):
        block = padded_text[i:i + 8]
        ciphertext += des_encrypt(block, subkeys)

    return ciphertext


def des_decrypt_text(ciphertext, key):
    """解密文本"""
    # 生成子密钥
    subkeys = generate_subkeys(key)

    # 分块解密
    plaintext = ''
    for i in range(0, len(ciphertext), 16):
        block = ciphertext[i:i + 16]
        plaintext += des_decrypt(block, subkeys)

    # 去除填充
    return unpad_text(plaintext)


def main():
    # 输入处理
    plaintext = input("请输入姓名拼音缩写: ")
    key = input("请输入密钥(8位字符): ")

    if len(key) != 8:
        print("密钥必须为8位字符!")
        return

    # 加密
    ciphertext = des_encrypt_text(plaintext, key)
    print("\n加密结果(16进制):", ciphertext)

    # 解密
    decrypted = des_decrypt_text(ciphertext, key)
    print("解密结果:", decrypted)

    # 验证
    if decrypted == plaintext:
        print("加解密验证成功!")
    else:
        print("加解密验证失败!")


if __name__ == "__main__":
    main()
posted @ 2025-04-23 15:28  lethe311  阅读(5)  评论(0)    收藏  举报