目录
背景
明文空间、密文空间及密钥空间都是长度为n的英文字母串的集合。因此可表示为P=C=K=(Z26) n。
加密变换如下:
设密钥k=(k1,k2,…,kn),明文M=(m1,m2,…,mn),加密函数为ek(M)=(c1,c2,…,cn), 其中
ci=(mi+ki) (mod 26),i=1,2,…,n。
对密文c=(c1,c2,…,cn),密钥k=(k1,k2,…,kn),解密变换为 dk(c)=(m1,m2,…,mn),其中 mi=(ci-ki) (mod 26),i=1,2,…,n。
示例:
设n=6,密钥是“cipher”,即密钥k=(2,8,15,7,4,17),明文是“this cryptosystem is not secure”,试用Vigenere密码对其加密。
解:首先将明文按每6个分为一组“thiscr/yptosy/stemis/ notsec/ure”,然后与密钥进行模26加得
明文: 19 7 8 18 2 17 24 15 19 14 18 24
密钥: 2 8 15 7 4 17 2 8 15 7 4 17
密文: 21 15 23 25 6 8 0 23 8 21 22 15
明文: 18 19 4 12 8 18 13 14 19 18 4 2
密钥: 2 8 15 7 4 17 2 8 15 7 4 17
密文: 20 1 19 19 12 9 15 22 8 25 8 19
明文: 20 17 4
密钥: 2 8 15
密文: 22 25 19
相应的密文是“VPXZGIAXIVWPUBTTMJPWIZITWZT”。
代码实现
Python:
key_code_min = {
'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8,
'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16,
'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25
}
def get_password(key, code):
# 定义字母与数字的对应关系
# 定义函数,按照指定长度分割字符串
def split_string_by_length(s, length):
return [s[i:i+length] for i in range(0, len(s), length)]
new_code = ''
# 按照密钥的长度分割字符串
str_arr = split_string_by_length(code, len(key))
for i in range(len(str_arr)):
for j in range(len(str_arr[i])):
num = (key_code_min[key[j]] + key_code_min[str_arr[i][j]]) % 26
# 找到对应的字母
new_code += next((k for k, v in key_code_min.items()
if v == num), None)
return new_code.upper()
def decrypt_password(key, code):
# 定义函数,按照指定长度分割字符串
def split_string_by_length(s, length):
return [s[i:i+length] for i in range(0, len(s), length)]
decoded_code = ''
# 按照密钥的长度分割字符串
str_arr = split_string_by_length(code.lower(), len(key))
for i in range(len(str_arr)):
for j in range(len(str_arr[i])):
num = (key_code_min[str_arr[i][j]] - key_code_min[key[j]]) % 26
# 找到对应的字母
decoded_code += next((k for k,
v in key_code_min.items() if v == num), None)
return decoded_code
print(get_password('cipher', 'thiscryptosystemisnotsecure'))
print(decrypt_password('cipher', 'VPXZGIAXIVWPUBTTMJPWIZITWZT'))
Javascript:
/**
* 实现古典加密算法
*/
const keyCodeMin = {
a: 0,
b: 1,
c: 2,
d: 3,
e: 4,
f: 5,
g: 6,
h: 7,
i: 8,
j: 9,
k: 10,
l: 11,
m: 12,
n: 13,
o: 14,
p: 15,
q: 16,
r: 17,
s: 18,
t: 19,
u: 20,
v: 21,
w: 22,
x: 23,
y: 24,
z: 25
}
const getPassword = (key, code) => {
//对code进行分割,按照key的长度进行分割
let newcode = ''
let strArr = splitStringByLength(code, key.length)
for (let i = 0; i < strArr.length; i++) {
for (let j = 0; j < strArr[i].length; j++) {
let num = (keyCodeMin[key[j]] + keyCodeMin[strArr[i][j]]) % 26
//拿到keyCodeMin中对应的字母
newcode += Object.keys(keyCodeMin).find((key) => keyCodeMin[key] === num)
}
}
return newcode.toLocaleUpperCase()
}
function splitStringByLength(str, length) {
const splitArray = []
let currentChunk = ''
for (let i = 0; i < str.length; i++) {
currentChunk += str[i]
if ((i + 1) % length === 0) {
splitArray.push(currentChunk)
currentChunk = ''
}
}
// 如果最后一个块不满足长度要求,也将其加入结果数组
if (currentChunk) {
splitArray.push(currentChunk)
}
return splitArray
}
//解密函数
const getDecode = (key, code) => {
let decodedCode = ''
const strArr = splitStringByLength(code.toLowerCase(), key.length)
for (let i = 0; i < strArr.length; i++) {
for (let j = 0; j < strArr[i].length; j++) {
const num = (keyCodeMin[strArr[i][j]] - keyCodeMin[key[j]] + 26) % 26
// 找到对应的字母
decodedCode += Object.keys(keyCodeMin).find((key) => keyCodeMin[key] === num)
}
}
return decodedCode
}
console.log(getPassword('cipher', 'thiscryptosystemisnotsecure')) // VPXZGIAXIVWPUBTTMJPWIZITWZT
console.log(getDecode('cipher', 'VPXZGIAXIVWPUBTTMJPWIZITWZT'))
c++:
#include <iostream>
#include <vector>
#include <string>
std::vector<std::string> splitStringByLength(const std::string& str, int length) {
std::vector<std::string> splitArray;
std::string currentChunk;
for (size_t i = 0; i < str.length(); ++i) {
currentChunk += str[i];
if ((i + 1) % length == 0) {
splitArray.push_back(currentChunk);
currentChunk.clear();
}
}
if (!currentChunk.empty()) {
splitArray.push_back(currentChunk);
}
return splitArray;
}
std::string getPassword(const std::string& key, const std::string& code) {
const std::unordered_map<char, int> keyCodeMin = {
{'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7},
{'i', 8}, {'j', 9}, {'k', 10}, {'l', 11}, {'m', 12}, {'n', 13}, {'o', 14}, {'p', 15},
{'q', 16}, {'r', 17}, {'s', 18}, {'t', 19}, {'u', 20}, {'v', 21}, {'w', 22}, {'x', 23},
{'y', 24}, {'z', 25}
};
std::string newcode;
std::vector<std::string> strArr = splitStringByLength(code, key.length());
for (size_t i = 0; i < strArr.size(); ++i) {
for (size_t j = 0; j < strArr[i].length(); ++j) {
int num = (keyCodeMin.at(key[j]) + keyCodeMin.at(strArr[i][j])) % 26;
newcode += std::string(1, std::find_if(keyCodeMin.begin(), keyCodeMin.end(),
[&](const std::pair<char, int>& p) { return p.second == num; })->first);
}
}
return newcode;
}
std::string getDecode(const std::string& key, const std::string& code) {
const std::unordered_map<char, int> keyCodeMin = {
{'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7},
{'i', 8}, {'j', 9}, {'k', 10}, {'l', 11}, {'m', 12}, {'n', 13}, {'o', 14}, {'p', 15},
{'q', 16}, {'r', 17}, {'s', 18}, {'t', 19}, {'u', 20}, {'v', 21}, {'w', 22}, {'x', 23},
{'y', 24}, {'z', 25}
};
std::string decodedCode;
std::vector<std::string> strArr = splitStringByLength(code, key.length());
for (size_t i = 0; i < strArr.size(); ++i) {
for (size_t j = 0; j < strArr[i].length(); ++j) {
int num = (keyCodeMin.at(strArr[i][j]) - keyCodeMin.at(key[j]) + 26) % 26;
decodedCode += std::string(1, std::find_if(keyCodeMin.begin(), keyCodeMin.end(),
[&](const std::pair<char, int>& p) { return p.second == num; })->first);
}
}
return decodedCode;
}
int main() {
std::cout << getPassword("cipher", "thiscryptosystemisnotsecure") << std::endl;
std::cout << getDecode("cipher", "VPXZGIAXIVWPUBTTMJPWIZITWZT") << std::endl;
return 0;
}
c:
#include <stdio.h>
#include <string.h>
struct KeyCodeMin {
char letter;
int value;
};
struct KeyCodeMin keyCodeMin[] = {
{'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7},
{'i', 8}, {'j', 9}, {'k', 10}, {'l', 11}, {'m', 12}, {'n', 13}, {'o', 14}, {'p', 15},
{'q', 16}, {'r', 17}, {'s', 18}, {'t', 19}, {'u', 20}, {'v', 21}, {'w', 22}, {'x', 23},
{'y', 24}, {'z', 25}
};
char* getPassword(const char* key, const char* code) {
char* newcode = "";
int keyLength = strlen(key);
int codeLength = strlen(code);
int i, j;
for (i = 0; i < codeLength; i += keyLength) {
for (j = 0; j < keyLength && i + j < codeLength; j++) {
int num = (keyCodeMin[key[j]].value + keyCodeMin[code[i + j]].value) % 26;
char letter = keyCodeMin[num].letter;
newcode += letter;
}
}
return newcode;
}
char* getDecode(const char* key, const char* code) {
char* decodedCode = "";
int keyLength = strlen(key);
int codeLength = strlen(code);
int i, j;
for (i = 0; i < codeLength; i += keyLength) {
for (j = 0; j < keyLength && i + j < codeLength; j++) {
int num = (keyCodeMin[code[i + j]].value - keyCodeMin[key[j]].value + 26) % 26;
char letter = keyCodeMin[num].letter;
decodedCode += letter;
}
}
return decodedCode;
}
int main() {
printf("%s\n", getPassword("cipher", "thiscryptosystemisnotsecure"));
printf("%s\n", getDecode("cipher", "VPXZGIAXIVWPUBTTMJPWIZITWZT"));
return 0;
}
java:
import java.util.HashMap;
public class ClassicEncryption {
static final HashMap<Character, Integer> keyCodeMin = new HashMap<>();
static {
keyCodeMin.put('a', 0);
keyCodeMin.put('b', 1);
keyCodeMin.put('c', 2);
keyCodeMin.put('d', 3);
keyCodeMin.put('e', 4);
keyCodeMin.put('f', 5);
keyCodeMin.put('g', 6);
keyCodeMin.put('h', 7);
keyCodeMin.put('i', 8);
keyCodeMin.put('j', 9);
keyCodeMin.put('k', 10);
keyCodeMin.put('l', 11);
keyCodeMin.put('m', 12);
keyCodeMin.put('n', 13);
keyCodeMin.put('o', 14);
keyCodeMin.put('p', 15);
keyCodeMin.put('q', 16);
keyCodeMin.put('r', 17);
keyCodeMin.put('s', 18);
keyCodeMin.put('t', 19);
keyCodeMin.put('u', 20);
keyCodeMin.put('v', 21);
keyCodeMin.put('w', 22);
keyCodeMin.put('x', 23);
keyCodeMin.put('y', 24);
keyCodeMin.put('z', 25);
}
public static String getPassword(String key, String code) {
StringBuilder newcode = new StringBuilder();
int keyLength = key.length();
int codeLength = code.length();
for (int i = 0; i < codeLength; i += keyLength) {
for (int j = 0; j < keyLength && i + j < codeLength; j++) {
int num = (keyCodeMin.get(key.charAt(j)) + keyCodeMin.get(code.charAt(i + j))) % 26;
newcode.append(getKeyByValue(num));
}
}
return newcode.toString();
}
public static String getDecode(String key, String code) {
StringBuilder decodedCode = new StringBuilder();
int keyLength = key.length();
int codeLength = code.length();
for (int i = 0; i < codeLength; i += keyLength) {
for (int j = 0; j < keyLength && i + j < codeLength; j++) {
int num = (keyCodeMin.get(code.charAt(i + j)) - keyCodeMin.get(key.charAt(j)) + 26) % 26;
decodedCode.append(getKeyByValue(num));
}
}
return decodedCode.toString();
}
public static char getKeyByValue(int value) {
for (char key : keyCodeMin.keySet()) {
if (keyCodeMin.get(key) == value) {
return key;
}
}
return '\0';
}
public static void main(String[] args) {
System.out.println(getPassword("cipher", "thiscryptosystemisnotsecure"));
System.out.println(getDecode("cipher", "VPXZGIAXIVWPUBTTMJPWIZITWZT"));
}
}