常见密码学编码及加密算法 / Common cryptographic coding and encryption algorithms
- 1. 费诺编码 / Ferno Encoding
- 2. 哈夫曼编码 / Huffman Encoding
- 3. 希尔密码 / Hill Cipher
- 4. 香农编码 / Shannon Encoding
- 5. DES 加密算法 / Data Encryption Standard (DES) Algorithm
- 6. ElGamal 加密算法 / ElGamal Public-key Cryptosystem
- 7. RSA 加密算法 / RSA algorithm
- 8. 高幂模求解 / High Power Modular Exponentiation Solution
1. 费诺编码 / Ferno Encoding
此程序为费诺编码的Python实现,但此版本存在缺陷:每个编码符号出现的概率不能相同。该问题在第二个程序得到改进。
第一个程序
'''
All rights reserved by Liu Junhong
Reference books: 《信息论基础》
Completion time:2020-11-24
'''
#import numpy as np
#import pandas
#import time
import math
#import sys
#程序说明
print("-------------------<费诺编码>程序说明-------------------")
print("Designed by Junhong Liu:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-费诺编码 (https://baike.baidu.com/item/%E8%B4%B9%E8%AF%BA%E7%BC%96%E7%A0%81)")
print("Completion time:2020-11-24")
print("Last modification time :2020-11-24")
print("--------------------------------------------------------")
print("\n")
#*******录入数据
N_num = float(input("请输入需要编码字符个数:"))
while(N_num <= 0 or (N_num % 1)):
N_num = float(input("请输入正整数:"))
N_num = int(N_num)
Dict = {}
probability = 1
while(N_num > 0):
N_num = N_num-1
print("\n","------还需输入",N_num,"编码字符信息------")
print("\n","请输入一个编码字符名:")
name = str(input())
Dict.setdefault(name)
print("请输入小于",probability,"的对应编码字符概率:")
value = float(input())
probability = probability - value
Dict[name] = value
#print(Dict)
#按概率排序
Dict_order=sorted(Dict.items(),key=lambda x:x[1],reverse=True)
#print(Dict_order)
#sys.exit(0)
#编码算法
name = []
value = []
#code = []
#truncation = 0 #保存截断位置
for i in Dict_order:
name.append(i[0])
value.append(i[1])
Fano_dict_value = {}.fromkeys(value,'')
#print(name)
#print(value)
value_copy = [value]
value_copy_copy = []
while(len(value_copy)>0):
for k in value_copy:
if len(k) == 2:
Fano_dict_value[k[0]] = Fano_dict_value[k[0]] + '0'
Fano_dict_value[k[1]] = Fano_dict_value[k[1]] + '1'
else:
for i in range(len(k)):
a = sum(k[:i])
b = sum(k[i:])
c = sum(k[:(i+1)])
d = sum(k[(i+1):])
if abs(a-b)<abs(c-d):
if i == 1:
Fano_dict_value[k[0]] = Fano_dict_value[k[0]] + '0'
value_copy_copy.append(k[1:])
for h in k[1:]:
Fano_dict_value[h] = Fano_dict_value[h] + '1'
else:
value_copy_copy.append(k[:i])
value_copy_copy.append(k[i:])
for j in k[:i]:
Fano_dict_value[j] = Fano_dict_value[j] + '0'
for h in k[i:]:
Fano_dict_value[h] = Fano_dict_value[h] + '1'
break
value_copy = value_copy_copy
value_copy_copy = []
#输出结果
Fano_dict = dict(zip(name,Fano_dict_value.values()))
print(Fano_dict)
第二个程序
'''
All rights reserved by Liu Junhong
Reference books: 《信息论基础》
Completion time:2020-11-24
'''
import math
#程序说明
print("-------------------<费诺编码>程序说明-------------------")
print("Designed by 刘俊宏:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-费诺编码 (https://baike.baidu.com/item/%E8%B4%B9%E8%AF%BA%E7%BC%96%E7%A0%81)")
print("Completion time:2020-11-24")
print("Last modification time :2020-11-25")
print("--------------------------------------------------------")
print("\n")
#*******录入数据
N_num = float(input("请输入需要编码字符个数:"))
while(N_num <= 0 or (N_num % 1)):
N_num = float(input("请输入正整数:"))
N_num = int(N_num)
Dict = {}
probability = 1
while(N_num > 0):
N_num = N_num-1
print("\n","------还需输入",N_num,"编码字符信息------")
print("\n","请输入一个编码字符名:")
name = str(input())
Dict.setdefault(name)
print("请输入小于",probability,"的对应编码字符概率:")
value = float(input())
probability = probability - value
Dict[name] = value
#按概率排序
Dict_order=sorted(Dict.items(),key=lambda x:x[1],reverse=True)
#编码算法
name = []
value = []
for i in Dict_order:
name.append(i[0])
value.append(i[1])
Fano_dict = {}.fromkeys(name,'')
value_copy = [value]
value_copy_copy = []
name_copy = [name]
name_copy_copy = []
while(len(value_copy)>0):
for k in range(len(value_copy)):
if len(value_copy[k]) == 2:
Fano_dict[name_copy[k][0]] = Fano_dict[name_copy[k][0]] + '0'
Fano_dict[name_copy[k][1]] = Fano_dict[name_copy[k][1]] + '1'
else:
for i in range(len(value_copy[k])):
a = sum(value_copy[k][:i])
b = sum(value_copy[k][i:])
c = sum(value_copy[k][:(i+1)])
d = sum(value_copy[k][(i+1):])
if abs(a-b)<abs(c-d):
if i == 1:
Fano_dict[name_copy[k][0]] = Fano_dict[name_copy[k][0]] + '0'
value_copy_copy.append(value_copy[k][1:])
name_copy_copy.append(name_copy[k][1:])
for h in name_copy[k][1:]:
Fano_dict[h] = Fano_dict[h] + '1'
else:
value_copy_copy.append(value_copy[k][:i])
value_copy_copy.append(value_copy[k][i:])
name_copy_copy.append(name_copy[k][:i])
name_copy_copy.append(name_copy[k][i:])
for j in name_copy[k][:i]:
Fano_dict[j] = Fano_dict[j] + '0'
for h in name_copy[k][i:]:
Fano_dict[h] = Fano_dict[h] + '1'
break
value_copy = value_copy_copy
name_copy = name_copy_copy
value_copy_copy = []
name_copy_copy = []
#输出结果
print(Fano_dict)
2. 哈夫曼编码 / Huffman Encoding
此程序为哈夫曼(Huffman)编码的Python实现
'''
All rights reserved by Liu Junhong
Reference books: 《信息论基础》
Completion time:2020-11-24
'''
import math
#程序说明
print("-------------------<哈夫曼编码>程序说明-------------------")
print("Designed by Junhong Liu:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-哈夫曼编码 (https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81/1719730?fr=aladdin)")
print("Completion time:2020-11-24")
print("Last modification time :2020-11-25")
print("--------------------------------------------------------")
print("\n")
#*******录入数据
N_num = float(input("请输入需要编码字符个数:"))
while(N_num <= 0 or (N_num % 1)):
N_num = float(input("请输入正整数:"))
N_num = int(N_num)
Dict = []
Huffman_dict = {}
probability = 1
while(N_num > 0):
N_num = N_num-1
print("\n","------还需输入",N_num,"编码字符信息------")
print("\n","请输入一个编码字符名:")
name = str(input())
Huffman_dict.setdefault(name)
Huffman_dict[name] = ''
print("请输入小于",probability,"的对应编码字符概率:")
value = float(input())
probability = probability - value
Dict.append((value,[name]))
#按概率排序
Dict_order=sorted(Dict,reverse=False)
#编码算法
Dict_order_copy = Dict_order
Dict_order_copy_copy = []
while(len(Dict_order_copy)>1):
for i in range(int(len(Dict_order_copy)/2)):
if len(Dict_order_copy)-2*(i+1) == 1:
for j in Dict_order_copy[2*i][1]:
Huffman_dict[j] = '0' + Huffman_dict[j]
for j in Dict_order_copy[2*i+1][1]:
Huffman_dict[j] = '1' + Huffman_dict[j]
Dict_order_copy_copy.append((Dict_order_copy[2*i][0]+Dict_order_copy[2*i+1][0],Dict_order_copy[2*i][1]+Dict_order_copy[2*i+1][1]))
Dict_order_copy_copy.append((Dict_order_copy[len(Dict_order_copy)-1][0],Dict_order_copy[len(Dict_order_copy)-1][1]))
else:
for j in Dict_order_copy[2*i][1]:
Huffman_dict[j] = '0' + Huffman_dict[j]
for j in Dict_order_copy[2*i+1][1]:
Huffman_dict[j] = '1' + Huffman_dict[j]
Dict_order_copy_copy.append((Dict_order_copy[2*i][0]+Dict_order_copy[2*i+1][0],Dict_order_copy[2*i][1]+Dict_order_copy[2*i+1][1]))
Dict_order_copy = sorted(Dict_order_copy_copy,reverse=False)
Dict_order_copy_copy = []
#输出结果
print(Huffman_dict)
3. 希尔密码 / Hill Cipher
3.1. C++
——————-<希尔密码(MOD27)>程序说明——————-
该程序目前只接受小写英文加密讯息(支持空格)!
每次运行程序,密钥都会改变!
该程序相较python版本有所删减,减小了码符集大小,但完善了密钥矩阵的生成条件,增强了安全性。
/*
All rights reserved by Liu Junhong
Reference books: 百度百科-希尔密码 、https://www.doc88.com/p-58447325494757.html)
Completion time:2021-4-10
*/
#include <iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <cstdlib>
#include <ctime>
using namespace std;
int p[9]; //P用于储存密钥矩阵
int main()
{
cout << "Designed by 刘俊宏:All rights reserved" <<endl;
cout << "Reference books: 百度百科-希尔密码 、https://www.doc88.com/p-58447325494757.html" <<endl;
cout << "Completion time:2021-4-6" <<endl;
cout << "Last modification time :2021-4-10" <<endl;
cout << "-------------------<希尔密码(MOD27)>程序说明-------------------" <<endl;
cout << "该程序目前只接受小写英文加密讯息(支持空格)!" <<endl;
cout << "每次运行程序,密钥都会改变!" <<endl;
cout << "该程序相较python版本有所删减,减小了码符集大小,但完善了密钥矩阵的生成条件,增强了安全性。" <<endl;
cout << "********************博客网址********************" <<endl;
cout << "欢迎访问:https://hong-king.github.io/" <<endl;
cout << "************************************************" <<endl;
cout << "---------------------------------------------------------------" <<endl;
/*
生成符合条件的3*3随机密钥矩阵
*/
int num;
srand((int)time(0)); //产生随机种子,把0换成NULL也行
do
{
for (int i = 0; i < 9; i++)
{
p[i] = rand()%27+1; //[1,53]
}
num = p[0]*p[4]*p[8] + p[1]*p[5]*p[6] + p[2]*p[3]*p[7] - p[2]*p[4]*p[6] - p[1]*p[3]*p[8] - p[0]*p[5]*p[7];
}while(num%3 == 0);
cout << "密钥:" << endl;
for (int i = 0; i < 9; i++)
{
cout << p[i] <<" ";
}
cout<<endl;
/*
求逆矩阵
*/
int num_mo;
for (int i = 1; i < 10000; i++){ //(i < 10000)存在BUG隐患
if ( (num*i)%27 == 1 || (num*i)%27 == -26 ){
num_mo = i;
break;
}
}
int I_p[9]; //P用于储存密钥的逆矩阵(转译矩阵)
I_p[0] = (((p[4]*p[8] - p[5]*p[7])*num_mo)%27 +27)%27;
I_p[3] = (((p[5]*p[6] - p[3]*p[8])*num_mo)%27 +27)%27;
I_p[6] = (((p[3]*p[7] - p[4]*p[6])*num_mo)%27 +27)%27;
I_p[1] = (((p[2]*p[7] - p[1]*p[8])*num_mo)%27 +27)%27;
I_p[4] = (((p[0]*p[8] - p[2]*p[6])*num_mo)%27 +27)%27;
I_p[7] = (((p[1]*p[6] - p[0]*p[7])*num_mo)%27 +27)%27;
I_p[2] = (((p[1]*p[5] - p[2]*p[4])*num_mo)%27 +27)%27;
I_p[5] = (((p[2]*p[3] - p[0]*p[5])*num_mo)%27 +27)%27;
I_p[8] = (((p[0]*p[4] - p[1]*p[3])*num_mo)%27 +27)%27;
/*
读取需要加密的信息
*/
string aaa;
cout << "请输入需要加密的信息(只能包含空格和小写字母):";
getline(cin,aaa); //getline用于读取整行数据
int g = aaa.length(); // 原始信息字数
int z = 3 - g%3; // 需要扩充的字数
if (z == 3)
z = 0;
int g_z = g + z; //扩充后的字数
int g_z_s = g_z / 3;
/*
将加密的信息转换成密文
*/
int information[g_z] = {0};
for (int i=0; i <= (g-1); i++)
{
if (int(aaa[i])==32)
information[i] = 0;
else if (int(aaa[i])>=97 && int(aaa[i])<=122)
{
information[i] = int(aaa[i]) - 96;
}
else
{
cout << "出现违法字符!" << endl;
break;
return 0;
}
}
int information_copy[g_z] = {0};
for (int i=0; i <= (g_z_s-1); i++)
{
information_copy[i*3+0] = (information[i*3+0]*p[0] + information[i*3+1]*p[1] + information[i*3+2]*p[2])%27;
information_copy[i*3+1] = (information[i*3+0]*p[3] + information[i*3+1]*p[4] + information[i*3+2]*p[5])%27;
information_copy[i*3+2] = (information[i*3+0]*p[6] + information[i*3+1]*p[7] + information[i*3+2]*p[8])%27;
}
cout<< "密文:"<<endl;
for (int i=0; i <= (g_z-1); i++)
{
if (information_copy[i]==0)
cout<<" ";
else if (information_copy[i]>=1 && information_copy[i]<=26)
{
cout << char(information_copy[i]+96);
}
}
/*
解码
*/
int information_copy_copy[g_z] = {0};
for (int i=0; i <= (g_z_s-1); i++)
{
information_copy_copy[i*3+0] = (information_copy[i*3+0]*I_p[0] + information_copy[i*3+1]*I_p[1] + information_copy[i*3+2]*I_p[2])%27;
information_copy_copy[i*3+1] = (information_copy[i*3+0]*I_p[3] + information_copy[i*3+1]*I_p[4] + information_copy[i*3+2]*I_p[5])%27;
information_copy_copy[i*3+2] = (information_copy[i*3+0]*I_p[6] + information_copy[i*3+1]*I_p[7] + information_copy[i*3+2]*I_p[8])%27;
if (information_copy_copy[i*3+0]<0)
information_copy_copy[i*3+0] = information_copy_copy[i*3+0] + 27;
if (information_copy_copy[i*3+1]<0)
information_copy_copy[i*3+1] = information_copy_copy[i*3+1] + 27;
if (information_copy_copy[i*3+2]<0)
information_copy_copy[i*3+2] = information_copy_copy[i*3+2] + 27;
}
cout<< "\n" << "明文:"<<endl;
for (int i=0; i <= (g_z-1); i++)
{
if (information_copy_copy[i]==0)
cout<<" ";
else if (information_copy_copy[i]>=1 && information_copy_copy[i]<=26)
{
cout << char(information_copy_copy[i]+96);
}
}
return 0;
}
运行结果示例:
Designed by 刘俊宏:All rights reserved
Reference books: 百度百科-希尔密码 、https://www.doc88.com/p-58447325494757.html
Completion time:2021-4-6
Last modification time :2021-4-10
-------------------<希尔密码(MOD27)>程序说明-------------------
该程序目前只接受小写英文加密讯息(支持空格)!
每次运行程序,密钥都会改变!
该程序相较python版本有所删减,减小了码符集大小,但完善了密钥矩阵的生成条件,增强了安全性。
********************博客网址********************
欢迎访问:https://hong-king.github.io/
************************************************
---------------------------------------------------------------
密钥:
1 14 7 21 19 27 13 10 15
请输入需要加密的信息(只能包含空格和小写字母):asd dfds
密文:
ydtqvv mz
明文:
asd dfds
3.2. Python
此程序为希尔密码(Hill Cipher)的Python实现
'''
All rights reserved by Liu Junhong
Reference books: 《信息论基础》、百度百科-希尔密码 (https://baike.baidu.com/item/%E5%B8%8C%E5%B0%94%E5%AF%86%E7%A0%81/2250150?fr=aladdin)
Completion time:2020-11-27
'''
import math
import numpy as np
import sys
#加/解密算法
def function(matrix):
List = []
STR = ''
for i in message:
for j in range(len(i)):
for h in i[j]:
List.append(letter_dict[h])
if len(i)- j > 1:
List.append(letter_dict[' '])
while(not len(List)%4 == 0):
List.append(letter_dict[' '])
B = np.array(List).reshape(-1,4)
C = np.dot(matrix,np.transpose(B))
for k in np.transpose(C).reshape(1,-1)[0]:
STR = STR + num_dict[(round(k))%53] #round()确保矩阵计算精度
print(STR)
List = []
STR = ''
#程序说明
print("Designed by 刘俊宏:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-希尔密码 (https://baike.baidu.com/item/%E5%B8%8C%E5%B0%94%E5%AF%86%E7%A0%81/2250150?fr=aladdin)")
print("Completion time:2020-11-27")
print("Last modification time :2020-11-28")
print("\n")
print("-------------------<希尔密码(MOD53)>程序说明-------------------")
print("该程序目前只接受大小写英文加密讯息(支持空格)!")
print("若要结束输入,请按两次回车")
print("每次运行程序,密钥都会改变!")
print("为保证解码顺利,密钥矩阵|A|=+/-1!")
print("\n")
print("********************博客网址********************")
print("欢迎访问:https://hong-king.github.io/")
print("************************************************")
print("---------------------------------------------------------------",'\n')
#创建码符集
letter = [' ']+[chr(i) for i in range(97, 123)] + [chr(i) for i in range(65, 91)]
letter_dict = dict(zip(letter,range(len(letter))))
num_dict = dict(zip(range(len(letter)),letter))
#*******录入数据
print("请输入需要加密的英文讯息:")
message = []
try:
while True:
m = sys.stdin.readline().strip() #若是多输入,strip()默认是以空格分隔,返回一个包含多个字符串的list。
if m == '':
break
m = list(m.split())
message.append(m)
except:
pass
print("正在加密,请稍后....")
#生成随机4阶可逆矩阵(密钥)
'''
为减小运算压力,设随机矩阵大小为4*4,随机整数元素区间为[1,10]
'''
A = np.random.randint(1, 10, size=(4,4)) #生成[1,10]区间的整数随机矩阵(密钥)
while (not abs(np.linalg.det(A)) == 1 ): #该条件用于保证密钥的逆矩阵为整数
A = np.random.randint(1, 10, size=(4,4))
A_Inv = np.linalg.inv(A)
print("-------------------密钥-------------------")
print(A)
print("-------------------密文-------------------")
function(A)
print("\n","****************解码****************")
print("请输入密文:")
message = []
try:
while True:
m = sys.stdin.readline().strip() #若是多输入,strip()默认是以空格分隔,返回一个包含多个字符串的list。
if m == '':
break
m = list(m.split())
message.append(m)
except:
pass
print("正在解密,请稍后....")
print("-------------------原文-------------------")
function(A_Inv)
4. 香农编码 / Shannon Encoding
此程序为香农编码的Python实现
'''
All rights reserved by Junhong Liu
Reference books: 《信息论基础》
Completion time:2020-11-23
'''
#import numpy as np
#import pandas
#import time
import math
#import sys
#程序说明
print("-------------------<香农编码>程序说明-------------------")
print("Designed by Junhong Liu:All rights reserved")
print("Reference books: 《信息论基础》、百度百科-香农编码 (https://baike.baidu.com/item/%E9%A6%99%E5%86%9C%E7%BC%96%E7%A0%81/22353186?fr=aladdin)")
print("Completion time:2020-11-23")
print("Last modification time :2020-11-23")
print("--------------------------------------------------------")
print("\n")
#*******录入数据
N_num = float(input("请输入需要编码字符个数:"))
while(N_num <= 0 or (N_num % 1)):
N_num = float(input("请输入正整数:"))
N_num = int(N_num)
Dict = {}
probability = 1
while(N_num > 0):
N_num = N_num-1
print("\n","------还需输入",N_num,"编码字符信息------")
print("\n","请输入一个编码字符名:")
name = str(input())
Dict.setdefault(name)
print("请输入小于",probability,"的对应编码字符概率:")
value = float(input())
probability = probability - value
Dict[name] = value
#print(Dict)
#按概率排序
Dict_order=sorted(Dict.items(),key=lambda x:x[1],reverse=True)
#print(Dict_order)
#sys.exit(0)
#编码算法
Q = 0 #累加概率
Shannon_dict = {}
for i in Dict_order:
P = i[1] #字符概率
L = math.ceil(-math.log(P,2)) #码长
Autoregressive_variable = 0
num = Q
word = "" #码字
while(Autoregressive_variable < L):
if int(num) < int(2*num):
word = word + '1'
num = 2*num - int(2*num)
else:
word = word + '0'
num = 2*num
Autoregressive_variable = Autoregressive_variable+1
Shannon_dict.setdefault(i[0])
Shannon_dict[i[0]] = word
Q = Q + P
print("Shannon_dict编码结果:",Shannon_dict)
#sys.exit(0)
5. DES 加密算法 / Data Encryption Standard (DES) Algorithm
程序说明 Reference books: https://blog.csdn.net/m0_37962600/article/details/79912654 Completion time:2021-4-20 Last modification time :2021-4-20
'''
此方法支持256种字符
参考文献:https://blog.csdn.net/m0_37962600/article/details/79912654
Completion time:2021-4-20
'''
import sys
#程序说明
print("-------------------<DES编码>程序说明-------------------")
print("All rights reserved")
print("Reference books: https://blog.csdn.net/m0_37962600/article/details/79912654)")
print("Completion time:2021-4-20")
print("Last modification time :2021-4-20",'\n')
print("--------------------------------------------------------")
print("请选择加密OR解密,加密输入0;解密输入1:")
aaaaa = input()
if (aaaaa != '0' and aaaaa != '1'):
print("输入有无!")
sys.exit(1)
#***************************************创建码符集
letter = [chr(i) for i in range(256)]
letter_dict = dict(zip(letter,['{:08b}'.format(i) for i in range(len(letter))]))
num_dict = dict(zip(['{:08b}'.format(i) for i in range(len(letter))],letter))
#***************************************生成16个子钥C,D(48位)(先假设密码为'12345678')
key = '12345678'
key_bin = ''
for i in key:
key_bin = key_bin+letter_dict[i]
#key_bin = '0001001100110100010101110111100110011011101111001101111111110001'
#----------------------------------------------------步骤一
EX = [57,49,41,33,25,17,9, #交换规则表(8*7)
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]
key_bIR = ''
for i in range(len(EX)):
key_bIR = key_bIR + key_bin[(EX[i]-1)]
#----------------------------------------------------步骤二
C = []
D = []
C.append(key_bIR[:28])
D.append(key_bIR[28:])
YW = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1] #移位规则表(1*16)
for i in range(16):
C.append(C[i][YW[i]:] + C[i][:YW[i]])
D.append(D[i][YW[i]:] + D[i][:YW[i]])
#----------------------------------------------------步骤三
PC_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]
K = []
for i in range(len(C)-1):
K_copy = C[i+1] + D[i+1]
K_IV = ''
for j in range(len(PC_2)):
K_IV = K_IV + K_copy[(PC_2[j]-1)]
K.append(K_IV)
#***************************************用得到的子密钥对64位数据加密
if (aaaaa == '0'):
print("请输入需要加密的英文讯息:")
else:
print("请输入需要解密的英文讯息:")
m = input()
if(len(m)%8 != 0):
m = m + num_dict['00000000']*(8 - len(m)%8)
M = []
for i in range(int(len(m)/8)):
M.append(m[i*8:i*8+8])
Ciphertext = ''
for i in M:
m = i
word_bin = ''
for i in m:
word_bin = word_bin+letter_dict[i]
#word_bin = '0000000100100011010001010110011110001001101010111100110111101111'
#----------------------------------------------------步骤一
IP = [58,50,42,34,26,18,10,2, #初始置换IP,得到word_bIR置换后的字符串
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]
word_bIR = ''
for i in range(len(IP)):
word_bIR = word_bIR + word_bin[(IP[i]-1)]
#初始置换IP,得到word_bIR
R = []
L = []
L.append(word_bIR[:32])
R.append(word_bIR[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]
for i in range(16):
L.append(R[i])
R_IV = ''
for j in range(len(E)):
if (aaaaa == '0'):
if ( R[i][(E[j]-1)] == K[i][j] ):
R_IV = R_IV + '0'
else:
R_IV = R_IV + '1'
else:
if ( R[i][(E[j]-1)] == K[15-i][j] ):
R_IV = R_IV + '0'
else:
R_IV = R_IV + '1'
S1 = [14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, #S核
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]
S = [S1,S2,S3,S4,S5,S6,S7,S8]
R_IV_2 = ''
for j in range(8):
IV = R_IV[j*6:j*6+6]
hang = IV[0]+IV[5]
hang = int(hang,2)
lie = IV[1:5]
lie = int(lie,2)
num = S[j][hang*16+lie]
R_IV_2 = R_IV_2 + '{:04b}'.format(num)
#----------------------------------------------------步骤三
P = [16,7,20,21, #P核
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]
R_IV_3 = ''
for j in range(len(P)):
if ( R_IV_2[(P[j]-1)] == L[i][j] ):
R_IV_3 = R_IV_3 + '0'
else:
R_IV_3 = R_IV_3 + '1'
R.append(R_IV_3)
#***************************************密文的生成
IP_1 = [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]
RL = R[16] + L[16]
Ciphertext_bin = ''
for i in range(len(IP_1)):
Ciphertext_bin = Ciphertext_bin + RL[(IP_1[i]-1)]
for j in range(8):
Ciphertext = Ciphertext + num_dict[Ciphertext_bin[j*8:j*8+8]]
if (aaaaa == '0'):
print("密文为:"+Ciphertext)
else:
print("明文为:"+Ciphertext)
6. ElGamal 加密算法 / ElGamal Public-key Cryptosystem
程序说明 ElGamal加密算法 Reference books: 《现代密码学(第二版)》 Reference books: https://blog.csdn.net/qq_41491942/article/details/103200388 Reference books: https://www.cnblogs.com/mx-lqk/p/10315789.html Completion time:2021-6-5 Last modification time :2021-6-5
import secrets
print("************程序功能************")
print("ElGamal加密算法")
print("********************************")
print("Reference books: 《现代密码学(第二版)》")
print("Reference books: https://blog.csdn.net/qq_41491942/article/details/103200388")
print("Reference books: https://www.cnblogs.com/mx-lqk/p/10315789.html")
print("Completion time:2021-6-5")
print("Last modification time :2021-6-5",'\n')
print("--------------------------------------------------------")
#高幂模
def gaomimo(a,b,P):
c = 1
if (b == 0):
return (c)
while(1):
if (b%2 != 0):
b = b-1
c = (c*a) % P
if (b == 0):
return (c)
else:
b = b//2
a = (a*a) % P
#米勒-拉宾素性检验
def judge_sushu(P):
if (P==2 or P==3):
return (1)
s = 1
while(1):
if((P-1)%(2**s) == 0):
s = s+1
else:
s = s-1
break
m = (P-1)//(2**s)
judge = 0
for b in range(1,(P-1),int((P-1)/10)):
r = 0
z = gaomimo(b,m,P)
if(z == 1 or z == P-1):
judge = judge + 1
continue
else:
while(1):
if (r == s-1):
return(0)
else:
r = r+1
z = gaomimo(z,2,P)
if(z == P-1):
continue
return(1)
#生成大素数p
q = secrets.randbelow(2**256)
if (q%2 == 0):
q = q+1
while(judge_sushu(q) == 0):
q = q+2
p = 2*q+1
print("生成大素数p中......")
while(judge_sushu(p) == 0):
q = q+2
while(judge_sushu(q) == 0):
q = q+2
p = 2*q+1
#p = 2579
#生成本原元g
print("\n","生成本原元g中......")
oula = p-1
g = 0
for i in range(secrets.randbelow(2**64),p):
g = i
if (gaomimo(g,1,p) == 1):
continue
else:
if (gaomimo(g,2,p) == 1):
continue
else:
if (gaomimo(g,q,p) == 1):
continue
else:
if (gaomimo(g,oula,p) == 1):
break
#g = 2
#生成公钥y及私钥x
print("\n","生成公钥y及私钥x中......")
x = secrets.randbelow(2**256)
while (not( 1<x and x<(p-2) )):
x = secrets.randbelow(2**256)
y = gaomimo(g,x,p)
#x = 765
#y = 949
#加密密文
print("\n","加密中......")
M = 1299 #明文M
k = secrets.randbelow(2**256)
while (not( 1<k and k<(p-2) ) or k==2 or k==q):
k = secrets.randbelow(2**256)
#k = 853
y1 = gaomimo(g,k,p)
U = gaomimo(y,k,p)
y2 = gaomimo(U*M,1,p)
print("密文:(",y1,",",y2,")")
#解密
print("\n","解密中......")
V = gaomimo(y1,x,p)
while(y2%V != 0): #用于修正参数,防止无法正确得到明文
y2 = y2 + p
M = gaomimo(y2//V,1,p)
print("明文为:",M)
print("\n","私钥x为:",x)
print("\n","公钥:")
print("p:",p)
print("\n","g:",g)
print("\n","y:",y)
7. RSA 加密算法 / RSA algorithm
程序说明 Reference books: 《现代密码学(第二版)》 Reference books: https://blog.csdn.net/jijianshuai/article/details/80582187 Reference books: https://baike.baidu.com/item/RSA%E7%AE%97%E6%B3%95/263310?fromtitle=RSA&fromid=210678&fr=aladdin#reference-[5]-10613-wrap Completion time:2021-6-4 Last modification time :2021-6-4
import secrets
print("************程序功能************")
print("求RSA加密算法")
print("********************************")
print("Reference books: 《现代密码学(第二版)》")
print("Reference books: https://blog.csdn.net/jijianshuai/article/details/80582187")
print("Reference books: https://baike.baidu.com/item/RSA%E7%AE%97%E6%B3%95/263310?fromtitle=RSA&fromid=210678&fr=aladdin#reference-[5]-10613-wrap")
print("Completion time:2021-6-4")
print("Last modification time :2021-6-4",'\n')
print("--------------------------------------------------------")
P = secrets.randbelow(2**1024)
if (P%2 == 0):
P = P+1
Q = secrets.randbelow(2**1024)
if (Q%2 == 0):
Q = Q+1
#求模逆
def moni(X,Y):
#第1步
n1 = Y
n2 = X
b1 = 0
b2 = 1
#第2步
q = n1//n2 #注意用//表示整数除法
r = n1-q*n2
#第3步
while (r != 0):
n1 = n2
n2 = r
t = b2
b2 = b1-q*b2
b1 = t
q = n1//n2
r = n1-q*n2
#第4步
ans = b2 % Y
if (n2 == 1):
return (ans)
else:
return (0)
#高幂模
def gaomimo(a,b,P):
c = 1
if (b == 0):
return (c)
while(1):
if (b%2 != 0):
b = b-1
c = (c*a) % P
if (b == 0):
return (c)
else:
b = b//2
a = (a*a) % P
#米勒-拉宾素性检验
def judge_sushu(P):
if (P==2 or P==3):
return (1)
s = 1
while(1):
if((P-1)%(2**s) == 0):
s = s+1
else:
s = s-1
break
m = (P-1)//(2**s)
judge = 0
for b in range(1,(P-1),int((P-1)/10)):
r = 0
z = gaomimo(b,m,P)
if(z == 1 or z == P-1):
judge = judge + 1
continue
else:
while(1):
if (r == s-1):
return(0)
else:
r = r+1
z = gaomimo(z,2,P)
if(z == P-1):
continue
return(1)
print("生成大素数中......")
while(judge_sushu(P) == 0):
P = P+2
while(judge_sushu(Q) == 0):
Q = Q+2
#print(P,"\n",Q)
#计算公共模数
N = P * Q
#欧拉函数
oula = (P-1)*(Q-1)
print("分配公钥及私钥中......")
#计算公钥E
E = min(P,Q)
D = 0
while(D == 0):
E = E - 2
while(judge_sushu(E) == 0):
E = E-2
#计算私钥D
D = moni(E,oula)
#print(D)
print("加密中......")
#公钥加密
M = 2
C = gaomimo(M,E,N)
#私钥加密
M = gaomimo(C,D,N)
print("初始明文为:2",'\n')
print("公钥为:",E,'\n')
print("私钥为:",D,'\n')
print("公共模数为:",N,'\n')
print("密文为:",C)
8. 高幂模求解 / High Power Modular Exponentiation Solution
程序说明 Reference books: https://www.cnblogs.com/linyujun/p/5194170.html Reference books: https://baike.baidu.com/item/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0/1944850?fr=aladdin#3_6 Completion time:2021-5-25 Last modification time :2021-5-25
import sys
import math
#参考文献:https://www.cnblogs.com/linyujun/p/5194170.html
print("************程序功能************")
print("求 【X^Y mod Z】 的值")
print("********************************")
print("Reference books: https://www.cnblogs.com/linyujun/p/5194170.html")
print("Reference books: https://baike.baidu.com/item/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0/1944850?fr=aladdin#3_6")
print("Completion time:2021-5-25")
print("Last modification time :2021-5-25",'\n')
print("--------------------------------------------------------")
print("请输入X:")
X = input()
X = int(X)
print("请输入Y:")
Y = input()
Y = int(Y)
print("请输入Z:")
Z = input()
Z = int(Z)
judge = 0 #接受Z是否为素数指令,0表示Z为素数,1表示Z不为素数
#判断Z是否为素数,并求出素数个数
def judge_sushu(P):
if (P==2 or P==3):
return (0)
dim = int(P**0.5)+1 #必须使用+1,不能使用ceil,否则4时出错
for i in range(2,dim):
if (P%i != 0 and i<(dim-1)):
continue
elif(P%i!=0 and i==(dim-1)):
return (0) #返回1说明P为素数
else:
return (i)
Prime_matrix = []
P = Z
Factor = judge_sushu(P)
if (Factor != 0):
judge = 1
while(1):
Prime_matrix.append(int(Factor))
P = P/Factor
if (judge_sushu(P) == 0):
Prime_matrix.append(int(P))
break
else:
Factor = judge_sushu(P)
else:
Prime_matrix.append(int(Z))
#求结果
Prime_set = list(set(Prime_matrix))
phi = Z
for i in range(len(Prime_set)):
phi = phi-phi/Prime_set[i] #欧拉函数值
ans = (int(X%Z)**int(phi+(Y%phi)))%Z #必须加上int,否则会转换成float类型,超出限制
print("结果为:")
print(ans)