希尔加密的原理就不多讲了,直接上代码。
定义一个函数:def fun(s, mod1, mod2, key)
s:要加密/解密的字符串
mod1:加密或解密
mod2:A=0或A=1,目前网络上的希尔加密都不是统一的,两种模式得出的结果是不一样的。
key:密钥,转换为矩阵后必须为方阵且可逆
要有传入的参数,key的长度为平方数,否则return
#边界条件
if not s:
return "请输入密文"
if not key:
return "请输入密钥"
l = int(len(key) ** 0.5)
if l ** 2 != len(key):
return "请输入有效密钥"
#统一转成小写字母,便于将字符串转成矩阵
s = s.lower()
key = key.lower()
#确定矩阵的长和宽
if len(s) % l == 0:
s_w = len(s) // l
else:
s_w = len(s) // l + 1
s_h = l
#初始化矩阵列表
ss = [[0 for _ in range(s_w)] for _ in range(s_h)]
keys = [[0 for _ in range(l)] for _ in range(l)]
对于上述的处理:不论加密还是解密,都是密钥x密文,或密钥的逆x密文,所以密文的高为密钥的边长,宽为:刚好构成一个矩阵,宽为总长度//l,不够则宽为总长度//l + 1。
下面对A=0和A=1分别处理s和key
#注意,矩阵是按列插入字母,如abcd,放到矩阵里是
#ac
#bd
#这里理解就行,不一定像我这样写
if mod_2 == "0":
for i in range(len(s)):
x = i // l
y = i % l
ss[y][x] += (ord(s[i]) - 97)
for i in range(len(key)):
x = i // l
y = i % l
keys[y][x] += (ord(key[i]) - 97)
elif mod_2 == "1":
for i in range(len(s)):
x = i // l
y = i % l
ss[y][x] += (ord(s[i]) - 96)
for i in range(len(key)):
x = i // l
y = i % l
keys[y][x] += (ord(key[i]) - 96)
else:
pass
用numpy处理刚刚的列表,让他们可以进行乘法运算。
ss = np.array(ss)
keys = np.array(keys)
对于密钥不可逆,直接return,如果为解密,则让他逆
if mod_1 == "d":
try:
keys = np.linalg.inv(keys)
except Exception:
return "密钥不可逆QAQ"
结果为
res = np.matmul(keys, ss)
最后将结果转为字符串
注意:
将矩阵的结果先模26,否则可能得不出正确结果
for i in range(s_w):
for j in range(l):
if mod_2 == "0":
it += chr((int(res[j][i]) % 26) + 97)
else:
it += chr((int(res[j][i])-1 % 26) + 97)
下面是完整代码
# 希尔加密/解密
def hill_ed(s, mod_1, mod_2, key):
if not s:
return "请输入密文"
if not key:
return "请输入密钥"
l = int(len(key) ** 0.5)
if l ** 2 != len(key):
return "请输入有效密钥"
s = s.lower()
key = key.lower()
if len(s) % l == 0:
s_w = len(s) // l
else:
s_w = len(s) // l + 1
s_h = l
ss = [[0 for _ in range(s_w)] for _ in range(s_h)]
keys = [[0 for _ in range(l)] for _ in range(l)]
if mod_2 == "0":
for i in range(len(s)):
x = i // l
y = i % l
ss[y][x] += (ord(s[i]) - 97)
for i in range(len(key)):
x = i // l
y = i % l
keys[y][x] += (ord(key[i]) - 97)
elif mod_2 == "1":
for i in range(len(s)):
x = i // l
y = i % l
ss[y][x] += (ord(s[i]) - 96)
for i in range(len(key)):
x = i // l
y = i % l
keys[y][x] += (ord(key[i]) - 96)
else:
pass
ss = np.array(ss)
keys = np.array(keys)
if mod_1 == "d":
try:
keys = np.linalg.inv(keys)
except Exception:
return "密钥不可逆QAQ"
res = np.matmul(keys, ss)
it = ""
for i in range(s_w):
for j in range(l):
if mod_2 == "0":
it += chr((int(res[j][i]) % 26) + 97)
else:
it += chr((int(res[j][i])-1 % 26) + 97)
return it
该工具已收录于https://www.awwwtaaa.net,点击右上角工具即可进入。