简述

希尔密码是利用矩阵进行加密的一种加密算法,其本质是一种多表代换密码。

  • 百科:
    希尔密码是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。
    每个字母当作26进制数字:A=0, B=1, C=2… 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模26。
    注意用作加密的矩阵(即密匙)在 必须是可逆的,否则就不可能解码。只有矩阵的行列式和26互质,才是可逆的。

希尔密码由于采用矩阵运算加密,因此在相同的明文加密时,可能会出现不同的密文,因此可以很好的抵御字母频率攻击法

加解密

  • 加密:

1、定义一个矩阵a(须存在逆矩阵)作为加密密钥:

[1,2,1]
[0,2,1]
[1,0,2]

2、将需要加密的明文字母转换为其对应的字母表数字(1-a,2-b……);
3、将转换后的明文数字序列按照密钥矩阵的阶数进行分组(如本次为3个字符一组);
4、每组数字序列和密钥矩阵进行矩阵的乘法运算(1x3 矩阵乘以 3x3矩阵),结果即为密文数字序列
5、可将密文数字序列转换为其对应字母,即为密文字符串

  • 解密:

解密流程与加密相同,唯一不同之处在于:需先求出加密密钥的逆矩阵

在做矩阵相成时,用密文分组乘以逆矩阵,结果即为明文

代码实现

#!/usr/bin/python3.7
# -*- coding: utf-8 -*-
# @Time    : 2019/12/11 14:53
# @Author  : SystemDefenser
# @Email   : mrwx1116@163.com
# @Software: PyCharmfrom numpy import linalg# 输入矩阵并判断是否存在逆矩阵
def inputMatrix():while True:# 输入一行、作为行列式的阶数和行列式的第一行rank = list(input("").split())matrix = [[0] * len(rank) for i in range(len(rank))]matrix[0] = rank# 输入行列式剩余数据for i in range(1, len(matrix)):matrix[i] = list(input("").split())# 判断每一行输入是否合法if len(matrix[i]) != len(matrix):print("输入有误,重新输入。")continue# 转换字符型为整型for i in range(len(matrix)):matrix[i] = list(map(lambda x: int(x), matrix[i]))# 判断是否存在逆矩阵if not judgeInverse(matrix):print("矩阵不存在逆矩阵,重新输入。")continuereturn matrix# 判断是否存在逆元
def judgeInverse(matrix):try:linalg.inv(matrix)except:return Falsereturn True# 生成密钥(矩阵的逆矩阵)
def createMatrixInverse(matrix):try:matrix_inverse = linalg.inv(matrix)except:return -1return matrix_inverse# 生成消息分组
def createMassageList(massage, matrix):matrixRank = len(matrix)massageList = []# 扩充消息序列并创建分组while len(massage) % matrixRank != 0:massage += " "for i in range(1, len(massage) + 1, matrixRank):massageList.append(massage[i-1:i + matrixRank - 1])return massageList# 字母序列转化为数字
def letterToDigit(massageList):massageDigitList = []  # 替换后的数字列表letterList = []  # 字母列表for i in range(ord("a"), ord("z") + 1):letterList.append(chr(i))for i in range(10):letterList.append(str(i))# 添加空格,解决分组填充问题letterList.append(" ")# 替换字母为数字for massage in massageList:listTmp = []for i in range(len(massage)):listTmp.append(letterList.index(massage[i]))massageDigitList.append(listTmp)return massageDigitList# 数字序列转化为字母
def digitToLetter(massageList):massageLetterList = []  # 还原后的字母列表letterList = []for i in range(ord("a"), ord("z") + 1):letterList.append(chr(i))for i in range(10):letterList.append(str(i))letterList.append(" ")# 替换数字为字母for massage in massageList:massageLetterList.append(letterList[massage % 37])return massageLetterList# 加密
def encrypt(massage, matrix):ciphertextList = [] # 加密结果列表massageList = createMassageList(massage, matrix)massageDigitList = letterToDigit(massageList)# 矩阵相乘for massageDigit in massageDigitList:for i in range(len(massageDigit)):sum = 0for j in range(len(massageDigit)):sum += massageDigit[j] * matrix[j][i % len(matrix)]ciphertextList.append(sum % 37)return ciphertextList# 解密
def decrypt(massage, matrix):plaintextList = []  # 解密结果列表matrix_inverse = createMatrixInverse(matrix)massageList = createMassageList(massage, matrix)# 矩阵相乘for msg in massageList:for i in range(len(msg)):sum = 0for j in range(len(msg)):sum += msg[j] * matrix_inverse[j][i % len(matrix)]plaintextList.append(sum % 37)# 浮点型转换为整型(采用四舍五入——round())plaintextList = list(map(lambda x: int(round(x)), plaintextList))plaintextList = digitToLetter(plaintextList)    # 数字转换为字母plaintext = ""for item in plaintextList:plaintext += itemreturn plaintextif __name__ == "__main__":while True:print("—————希尔密码—————")choice = input("1、加密        2、解密\n请选择:")if choice == "1":print("输入矩阵:")matrix = inputMatrix()massage = input("输入msg:")massageList = createMassageList(massage, matrix)ciphertextList = encrypt(massage, matrix)print("加密结果:", ciphertextList)elif choice == "2":massageList = list(map(int, list(input("输入密文序列:").split(","))))print("输入矩阵:")matrix = inputMatrix()matrix_inverse = createMatrixInverse(matrix)print("逆矩阵:")for item in matrix_inverse:print(item)plaintext = decrypt(massageList, matrix)print("解密结果:", plaintext)

其中,求逆矩阵部分未能手算,调用了numpy库中的linalg函数,惭愧………………

加密测试

—————希尔密码—————
1、加密        2、解密
请选择:1
输入矩阵:
1 0 1 1
0 1 0 1
1 1 0 0
1 1 0 1
输入msg:systemdefenser
加密结果: [18, 24, 18, 24, 11, 19, 4, 20, 36, 35, 5, 27, 2, 15, 4, 20]
—————希尔密码—————
1、加密        2、解密
请选择:2
输入密文序列:18, 24, 18, 24, 11, 19, 4, 20, 36, 35, 5, 27, 2, 15, 4, 20
输入矩阵:
1 0 1 1
0 1 0 1
1 1 0 0
1 1 0 1
逆矩阵:
[ 0. -1.  0.  1.]
[ 0.  1.  1. -1.]
[ 1.  1.  1. -2.]
[ 0.  0. -1.  1.]
解密结果: systemdefenser
  • 加密:

  • 解密:

部分代码详解

  • 输入矩阵部分

代码片段:

while True:# 输入一行、作为行列式的阶数和行列式的第一行rank = list(input("").split())matrix = [[0] * len(rank) for i in range(len(rank))]matrix[0] = rank# 输入行列式剩余数据for i in range(1, len(matrix)):matrix[i] = list(input("").split())# 判断每一行输入是否合法if len(matrix[i]) != len(matrix):print("输入有误,重新输入。")continue

该片段位于 inputMatrix() 函数中。

输入矩阵部分未让用户先定义阶数,而是通过用户输入的矩阵第一行,来决定本次迷药矩阵的阶数,并且不断进行合法判断。

  • 解密部分

代码片段:

 # 浮点型转换为整型(采用四舍五入——round())plaintextList = list(map(lambda x: int(round(x)), plaintextList))plaintextList = digitToLetter(plaintextList)    # 数字转换为字母

该片段位于 decrypt(massage, matrix) 函数中。

由于逆矩阵存在不可约分或整除的小数,因此在此处采用四舍五入round(x) 的方法不严谨地解决此问题。

hill密码(希尔密码)相关推荐

  1. Hill Cipher 希尔密码 已知明文密文 求秘钥方法

    Hill Cipher,已知明文密文,求秘钥 设K为秘钥, 为明文字母对应的数字矩阵, 为密文字母对应的数字矩阵. 是希尔加密的过程. 为了求解K,我们需要求解P的膜26逆元. 注意,这里是膜26逆元 ...

  2. Visual Studio 2019下用 C# 实现 Hill2 二阶希尔密码 的加密、解密 GUI界面

    1.什么是Hill2 什么是Hill密码 希尔密码(Hill)使用每个字母在字母表中的顺序作为其对应的数字,即 A=0,B=1,C=2 等,然后将明文转化为 n 维向量,跟一个 n × n 的矩阵相乘 ...

  3. C++希尔密码Hill Cipher算法(附完整源码)

    希尔密码Hill Cipher的算法 希尔密码(Hill Cipher) 的算法的完整源码(定义,实现,main函数测试) 希尔密码(Hill Cipher) 的算法的完整源码(定义,实现,main函 ...

  4. 08:vigenère密码_密码技术:Vigenére密码,Playfair密码,Hill密码

    08:vigenère密码 1)Vigenére密码 (1) Vigenére Cipher) This technique is an example of Polyalphabetic Subst ...

  5. C++希尔密码的实现以及运用

    希尔密码(Hill Cipher)是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明.每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n维向量,跟一 ...

  6. 希尔密码在CTF中应用—记一道题

    CTF-crypto 解题思路来自:i春秋的大佬们 https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=52687&highli ...

  7. JavaScript实现希尔密码 算法(附完 整源码)

    JavaScript实现希尔密码 算法 Matrix.js完整源代码 hillCipher.js完整源代码 hillCipher.test.js完整源代码 Matrix.js完整源代码 export ...

  8. linux 正则 设置密码复杂度,Ubuntu修改密码及密码复杂度策略设置方法

    一.修改密码 1.修改普通用户密码 passwd 先输入当前密码确认,然后输入新的密码修改 2.修改root用户密码 sudo passwd root 默认root用户被禁止登录,如果需要解除限制,修 ...

  9. shell批量创建和删除10个系统帐号密码(密码为随机10位字符串)

    1.添加10个用户和密码,并把账号和密码保存到指定的文件里 # vim create_user.sh #/bin/bash # for jiangjj in {1..10}; do if id use ...

  10. php 挂马 密码123456,admin密码-常用密码加密md5值,123456,admin,admin888

    一 : 常用密码加密md5值,123456,admin,admin888 123456这个经md5算法加密之后是多少? 16位:49ba59abbe56e057 32位:e10adc3949ba59a ...

最新文章

  1. 摇滚吧HTML5!Jsonic超声波前端交互!
  2. 如何使用Fiddler调试线上JS代码(转自:http://www.cnblogs.com/RockLi/p/3511132.html)
  3. js 面向对象例子
  4. 合格网络管理员需了解的主要职责
  5. 《C++ Primer 第五版》(第6.3~6.7节)——返回指向数组/函数的指针,函数重载,默认形参、inline函数和constexpr函数
  6. 这些行为,属于学术不端!
  7. 像搭“乐高”一样实现整合式网络安全体系
  8. 这才是男朋友该说的话^_^
  9. jetty java 禁用目录列表_Apache httpd 目录列表禁用配置(options indexes)
  10. Dell Inspiron 3443 BIOS升级问题解决
  11. 不错的Unity教程
  12. 关闭Word提示无法将更改后的内容保存到共用模板
  13. 使用PhantomJS网页截图
  14. 背景图页面缩小会变形_CSS背景图拉伸不变形
  15. 1、定义一个复数类Complex,使得下面的代码能够工作。 Complex c1(3,5); Complex c2=4.5; c1.add(c2); c1.show();
  16. JVM内存分哪几个区,每个区的作用是什么?
  17. linux hwclock -r显示的HWC TIME(硬件时钟时间)与timedatectl结果中的RTC TIME(实时时钟时间)有什么区别?BIOS时钟源
  18. 2022-2028全球超声波封管机行业调研及趋势分析报告
  19. 一款mipi转lvds的lcd调试(lt8912b)
  20. 计算机毕业设计Java家电产品售后(源码+系统+mysql数据库+lw文档)

热门文章

  1. Wincc声音报警简单方法
  2. 软件开发人员的简历项目经验怎么写
  3. 从选课系统看软件开发周期
  4. 视音频处理大神-雷霄骅
  5. typedef用法和结构体指针用法
  6. php小程序秒抢高并发,微信小程序的10个请求并发限制的优化消息!!!
  7. [Matlab科学计算] 有限元法求二阶常微分方程
  8. 程序员10大修炼之道,学会这些月入百万不是梦
  9. CASA方法估算NPP(IDL+ENVI)
  10. (轉貼) 人人有功練!! 有功夫,沒懦夫 (News)