这种加密本质上是换汤不换药的,我们需要有所创新,下面是我的想法(key{A}和key{B}表示的是A和B独有的秘钥):
假设现在有服务器192.168.1.1,本机扮演角色A,服务器扮演角色B,进行如下逻辑:A拥有A的专属秘钥(汉字秘钥)进行一次加密发送给B,B接受到后再用B的专属秘钥再次加密发送给A,然后A接受到有两次加密的内容后用A的秘钥解开一次内容再发给B,B接收到后用B的秘钥解开查看内容,以helloword为内容,代码如下:
加密解密函数模块
#include <iostream>
#include <unordered_map>
#include <string>// 定义角色 A 和 B 的专属秘钥
std::unordered_map<char, std::string> AKey = {{'h', "海"}, {'e', "恩"}, {'l', "兰"}, {'o', "欧"}, {'w', "威"},{'r', "荣"}, {'d', "达"}, {'H', "汉"}, {'E', "尔"}, {'L', "理"},{'O', "奥"}, {'W', "王"}, {'R', "日"}, {'D', "德"}, {' ', " "},
};std::unordered_map<char, std::string> BKey = {{'h', "鸿"}, {'e', "艺"}, {'l', "雷"}, {'o', "欧"}, {'w', "文"},{'r', "仁"}, {'d', "东"}, {'H', "和"}, {'E', "恩"}, {'L', "流"},{'O', "奥"}, {'W', "沃"}, {'R', "瑞"}, {'D', "大"}, {' ', " "},
};// 打表加密函数
std::string encrypt(const std::string& input, const std::unordered_map<char, std::string>& key) {std::string encryptedText = "";for (char c : input) {if (key.find(c) != key.end()) {encryptedText += key.at(c); // 查表加密} else {encryptedText += c; // 未定义字符直接保留}}return encryptedText;
}// 打表解密函数(反向映射)
std::string decrypt(const std::string& input, const std::unordered_map<char, std::string>& key) {// 构造反向映射表std::unordered_map<std::string, char> reverseKey;for (const auto& pair : key) {reverseKey[pair.second] = pair.first;}std::string decryptedText = "";std::string buffer = ""; // 用于存储汉字缓冲for (char c : input) {if ((unsigned char)c >= 0x80) { // 判断是否为汉字(中文多字节编码)buffer += c;// 完成一个汉字if (buffer.size() == 3) {if (reverseKey.find(buffer) != reverseKey.end()) {decryptedText += reverseKey[buffer]; // 查表解密} else {decryptedText += buffer; // 未定义字符直接保留}buffer.clear();}} else {decryptedText += c; // 非汉字字符直接追加}}return decryptedText;
}
角色 A 的代码
角色 A 扮演客户端,连接到服务器 B,发送和接收数据。
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "encryption_module.h" // 包含加密解密逻辑#define SERVER_IP "127.0.0.1" // 或者替换为 "192.168.1.1"
#define SERVER_PORT 8080int main() {// 创建 Socketint clientSocket = socket(AF_INET, SOCK_STREAM, 0);if (clientSocket < 0) {std::cerr << "Socket creation failed!" << std::endl;return -1;}// 设置服务器地址sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);inet_pton(AF_INET, SERVER_IP, &serverAddr.sin_addr);// 连接服务器if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {std::cerr << "Connection to server failed!" << std::endl;close(clientSocket);return -1;}// 原始消息std::string message = "helloworld";std::cout << "原始消息: " << message << std::endl;// A 使用 AKey 加密std::string encryptedByA = encrypt(message, AKey);send(clientSocket, encryptedByA.c_str(), encryptedByA.size(), 0);std::cout << "A 加密后发送: " << encryptedByA << std::endl;// 接收 B 的加密消息char buffer[1024] = {0};int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);std::string encryptedByB(buffer, bytesReceived);std::cout << "A 收到双重加密消息: " << encryptedByB << std::endl;// A 解密一次std::string decryptedByA = decrypt(encryptedByB, AKey);std::cout << "A 解密后发送给 B: " << decryptedByA << std::endl;send(clientSocket, decryptedByA.c_str(), decryptedByA.size(), 0);// 关闭连接close(clientSocket);return 0;
}
角色 B 的代码
角色 B 扮演服务器,接收来自 A 的消息,加密后再发送回去。
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "encryption_module.h" // 包含加密解密逻辑#define SERVER_PORT 8080int main() {// 创建 Socketint serverSocket = socket(AF_INET, SOCK_STREAM, 0);if (serverSocket < 0) {std::cerr << "Socket creation failed!" << std::endl;return -1;}// 绑定地址和端口sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);serverAddr.sin_addr.s_addr = INADDR_ANY;if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {std::cerr << "Bind failed!" << std::endl;close(serverSocket);return -1;}// 监听连接if (listen(serverSocket, 1) < 0) {std::cerr << "Listen failed!" << std::endl;close(serverSocket);return -1;}std::cout << "等待客户端连接..." << std::endl;// 接受连接sockaddr_in clientAddr;socklen_t clientLen = sizeof(clientAddr);int clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientLen);if (clientSocket < 0) {std::cerr << "Accept failed!" << std::endl;close(serverSocket);return -1;}std::cout << "客户端已连接!" << std::endl;// 接收 A 的加密消息char buffer[1024] = {0};int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);std::string encryptedByA(buffer, bytesReceived);std::cout << "B 收到 A 的消息: " << encryptedByA << std::endl;// B 使用 BKey 加密std::string encryptedByB = encrypt(encryptedByA, BKey);send(clientSocket, encryptedByB.c_str(), encryptedByB.size(), 0);std::cout << "B 加密后发送: " << encryptedByB << std::endl;// 接收 A 解密后的消息bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);std::string decryptedByA(buffer, bytesReceived);std::cout << "B 收到 A 解密后的消息: " << decryptedByA << std::endl;// B 解密std::string finalMessage = decrypt(decryptedByA, BKey);std::cout << "B 解密后的消息: " << finalMessage << std::endl;// 关闭连接close(clientSocket);close(serverSocket);return 0;
}
运行说明
先启动角色 B(服务器)。
再启动角色 A(客户端)。
角色 A 和角色 B 会进行多轮消息加密、解密和传输,最终在角色 B 的终端上看到解密后的原始消息helloworld。
结果示例
A 发送加密消息:海恩兰兰欧威欧荣兰达
B 接收到后再次加密:鸿艺雷雷欧文欧仁雷东
A 解密后发送给 B:海恩兰兰欧威欧荣兰达
B 最终解密得到原文:helloworld