仿射密码
def fangshe_encrypt(m, a, b):
res = ''
for i in range(len(m)):
if m[i] >= 'A' and m[i] <= 'Z':
res += chr(((ord(m[i]) - 65) * a + b) % 26 + 65)
return res
def get_re(a): #得逆元
for i in range(1, 27): #因为数量较小,就直接一一匹配
if i * a % 26 == 1:
return i
def fangshe_decrypt(c, a, b):
res = ''
a_1 = get_re(a)
for i in range(len(c)):
if c[i] >= 'A' and c[i] <= 'Z':
res += chr((((ord(c[i]) - 65) - b) * a_1) % 26 + 65)
return res
m = input("plz input your plaintext(A~Z):")
#m = 'ILOVEFANGSHE'
a = 19
b = 3
c = fangshe_encrypt(m, a, b)
print("加密后结果:",c)
d = fangshe_decrypt(c, a, b)
print("解密后结果:",d)
维吉尼亚密码
w ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def create_k_list(k): #创建密钥数据形式
res = []
for i in range(len(k)):
res.append(ord(k[i].upper())-65) #全部大写
return res
def Vigenere_encrypt(m,k):
res = ''
K = create_k_list(k) #创建密钥数据形式
t = 0 #存放K的下标
for i in range(len(m)):
if t == len(K):
t = 0
if m[i]>='A' and m[i]<='Z':
res += w[(ord(m[i]) + K[t] - 65) % 26]
t +=1
elif m[i]>='a' and m[i]<='z':
res += w[(ord(m[i])+K[t]-97)%26]
t+=1
else:
res += m[i]
return res
def Vigenere_decrypt(c,k):
res = ''
K = create_k_list(k)
t = 0
for i in range(len(c)):
if t == len(K):
t = 0
if c[i]>='A' and c[i]<='Z':
res += w[(ord(c[i]) - K[t] - 65) % 26]
t +=1
elif c[i]>='a' and c[i]<='z':
res += w[(ord(c[i])-K[t]-97)%26]
t+=1
else:
res += c[i]
return res
flag = input("输入E加密,输入D解密:")
if flag == 'E':
m = input("请输入明文:")
k = input("请输入密钥:")
c = Vigenere_encrypt(m, k)
print("加密结果为:",c)
elif flag == 'D':
c = input("请输入密文:")
k = input("请输入密钥:")
d = Vigenere_decrypt(c, k)
print("解密结果为:",d)
# m = 'ILOVEVIGENERE'
# m = 'WhenthemediareportnewsaboutChinesesecondrichgenerationtheyareoftendescribedtobeviolentrudeandimpoliteTheserichkidslivethecomfortablelifebuttheirparentshaventeducatedthemwellbecausetheyarebusywiththeirbusinessOrthesekidsaresenttostudyabroadtheyarestillthewildchildren'
# k = 'thisiskey'
# c = Vigenere_encrypt(m,k)
# print("加密结果为:",c)
# d = Vigenere_decrypt(c, k)
# print("解密结果为:",d)
线性反馈移位寄存器
# 本原多项式:x^17 + x^3 + 1
a = [0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0,1] #初始状态
aa = [0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0,1] #对比状态
count = 0
print("预期周期是:",2**17-1)
while True:
b = (a[0] + a[14]) %2
a.append(b) #右进,左出,是相反的
del a[0]
count += 1
if a == aa:
print("运算后的周期是:",count)
break
RSA
import random
import libnum
#扩展欧几里得算法。
def ex_gcd(a, b):
if b == 0:
return 1, 0
else:
q = a // b
r = a % b
s, t = ex_gcd(b, r)
s, t = t, s - q * t
return [s, t]
# Miller Rabin算法检验
def rabin_miller(num):
s = num - 1
t = 0
while s % 2 == 0: # 如果是偶数,直到奇数
s = s // 2 # 整除2
t += 1 # 记录除的次数
for trials in range(15): #15次检验
a = random.randrange(2, num - 1) # 生成随机数
v = pow(a, s, num) # (a**num-1) %num 费马小定理,余数为v
if v != 1: # 如果模不等于1
i = 0
while v != (num - 1): # 就是 v自乘取模后不为1,就继续
if i == t - 1: # 当t-1次,仍不为1,就是 v ** (2 ** t-1) != 1 mod num
return False # 失败,费马定理失败,则一定是合数
else:
i = i + 1 # 次数+1
v = (v ** 2) % num # 自乘取模
# 如果v自乘取模后为1,费马定理成功,有一定概率是素数
# 15次检验都成功,极大概率是素数。
return True
# 判断是否为素数
def is_prime(num):
# 排除0,1和负数
if num < 2:
return False
# 创建小素数的列表,可以大幅加快速度
# 如果是小素数,那么直接返回true
small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
991, 997]
if num in small_primes:
return True
# 若大数能整除小素数,则错误,是合数
for prime in small_primes:
if num % prime == 0:
return False
# 若以上均通过,用rabin_miller算法检验
return rabin_miller(num)
# 得到大整随机数
def get_prime(key_size):
while True:
# 生成随机数,范围是[2**(key_size-1), 2**key_size)
num = random.randrange(2 ** (key_size - 1), 2 ** key_size)
# 判断是否是素数
if is_prime(num):
return num
# 快速幂
def qmi(a, b, p):
res = 1
while b:
if b & 1: # 最小位是否为1
res = res * a % p
a = a * a % p
b >>= 1
return res
# 创建d
def create_d(e, f_n):
d = ex_gcd(e, f_n)[0]%f_n # 扩展欧几里德,辗转相除得到d。
return d
# 创建各种参数
def create_p_q_n_f_n_e_d():
p = get_prime(1024)
q = get_prime(1024)
n = p * q
f_n = (p - 1) * (q - 1)
e = 65537
d = create_d(e, f_n)
return p, q, n, f_n, e, d
# 加密
def RSA_encrypt(m, e, n):
M = "".join("{:02x}".format(ord(x)) for x in m)
M = int(M, 16)
return qmi(M, e, n) # C = M^e (mod n)
# 解密
def RSA_decrypt(c, d, n):
res = pow(c, d, n) # plaintext = C^d (mod n)
res = str(bytes.fromhex('{:x}'.format(res)))
return res[2:len(res) - 1]
m = input("plz input your plaintext:")
# 生成各种参数
p, q, n, f_n, e, d = create_p_q_n_f_n_e_d()
# 加密
C = RSA_encrypt(m, e, n)
print("加密后数据为:", C)
# 解密
M = RSA_decrypt(C, d, n)
print("解密后数据为:", M)
MD5
import math
#左移位数数组
r = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
]
#正弦函数
T = [int(math.floor(abs(math.sin(i + 1)) * (2 ** 32))) for i in range(64)]
# 字符串转二进制
def str_to_bin(input):
input1 = input.encode("utf-8").hex()
res = ''
for i in range(len(input1)):
res += bin(int(input1[i], 16))[2:].rjust(4, "0")
return res
#填充0-1
def add_0_1(input): # 最后长度直接填在最后
l = bin(len(input))[2:] #取二进制输入字符串的长度
res = input
flag = 0
# 填充10
while len(res) % 512 != 448: #填充一个1和若干0
if flag == 0:
res += '1'
flag = 1
else:
res += '0'
while (len(res) + len(l)) % 512 != 0: #高位补齐0
res += '0'
res += l #填充长度数据
return res
# 初始化寄存器
def create_register(): # 小端序后
A = 0x67452301
B = 0xefcdab89
C = 0x98badcfe
D = 0x10325476
return A, B, C, D
#二进制转512数组
def bin_to_512hexarr(input):
res = []
rehex = ''
inhex = ''
if len(input) % 512 != 0:
print("wrong1!!")
return 0
else:
# 除最后前512位,先全部转16进制,再八位置换, 再放进数组
for i in range(len(input) - 512):
inhex = hex(int(input[0:len(input) - 512], 2))[2:]
for i in range(len(inhex) // 8):
re = ''
for t in range(7, -1, -2):
rehex += inhex[i * 8:i * 8 + 8][t - 1:t + 1]
for i in range(len(rehex) // 128):
res.append(rehex[i * 128:i * 128 + 128])
# 取最后512位
a = input[len(input) - 512:len(input)]
# 对剩下的512bit操作,前448同上操作,后64bit填入长度
# 前448位转16进制
b = hex(int(a[0:448], 2))[2:]
# 前448位小端序
res1 = ''
for i in range(len(b) // 8):
c = b[i * 8:i * 8 + 8] # 每八位放在c中
for j in range(7, -1, -2):
d = c[j - 1:j + 1] # 倒叙结果
res1 += d
# 最后64位
num = hex(int(a[448:512], 2))[2:]
if len(num) <= 8: # 如果小于8位,就先放高位,然后再放低位0
res1 += num.rjust(8, "0")
for i in range(8):
res1 += "0"
else:
num1 = num[0:8]
num2 = num[8:]
res1 += num1
res1 += num2.rjust(8, "0")
res.append(res1)
return res
#512bit数组转32bit
def hexarr_512_to_32(input):
if len(input) != 128: # 128组
print("wrong2")
return 0
else:
res = []
for i in range(16):
res.append(input[i * 8:i * 8 + 8])
return res
#左移
def leftround(input, round):
return (input << round | input >> (32 - round)) & 0xffffffff
#ABCD组合,小端序排列相加
def conclude_ABCD(A, B, C, D):
res = ''
A = hex(A)[2:]
B = hex(B)[2:]
C = hex(C)[2:]
D = hex(D)[2:]
for i in range(7, -1, -2):
a = A[i - 1:i + 1]
res += a
for i in range(7, -1, -2):
a = B[i - 1:i + 1]
res += a
for i in range(7, -1, -2):
a = C[i - 1:i + 1]
res += a
for i in range(7, -1, -2):
a = D[i - 1:i + 1]
res += a
return res
#字符串转16进制
def str_to_hex(input):
if len(input) != 8:
print("wrong")
return 0
else:
res = 0
for i in range(len(input)):
a = int(input[i], 16)
b = a << 4
c = res << 4
d = c + a
res = d
return res
#md5加密函数
def md5_hash(input):
bin_str = str_to_bin(input) #ascii变成01进制字符串
whole_bin_str = add_0_1(bin_str) #附加填充位
A, B, C, D = create_register() #初始化链接变量
# 将附加填充为后的二进制字符串分成512bit为一组的Mi分组,同时对其进行小端化处理
hex_512arr = bin_to_512hexarr(whole_bin_str)
for i in range(len(hex_512arr)): #分别对每个Mi进行hash
hex_32arr = hexarr_512_to_32(hex_512arr[i]) # 每个Mi分成32bit为一组的mi,共16组
AA, BB, CC, DD = A, B, C, D #寄存器初始值备份
for j in range(64): #4轮16个步函数,共64步
if j < 16:
f = (B & C) | ((~B) & D) #非线性函数
flag = j #m[i] 即书上的M[j]
elif j < 32:
f = (B & D) | (C & (~D))
flag = (5 * j + 1) % 16
elif j < 48:
f = (B ^ C ^ D)
flag = (3 * j + 5) % 16
else:
f = C ^ (B | (~D))
flag = (7 * j) % 16
#步函数执行过程
temp = B + leftround((A + f + T[j] + str_to_hex(hex_32arr[flag])) & 0xffffffff, r[j])
#寄存器换位
A, B, C, D = D, temp & 0xffffffff, B, C
A = (A + AA) & 0xffffffff #执行完寄存器A和备份相加
B = (B + BB) & 0xffffffff
C = (C + CC) & 0xffffffff
D = (D + DD) & 0xffffffff
res = conclude_ABCD(A, B, C, D) #四个寄存器值小端序组合拼接
return res
input = input("plz input your plain text:")
#input = 'iscbupt'
a = md5_hash(input)
print(a)