维吉尼亚密码方阵

2023-11-09 12:50
文章标签 密码 方阵 维吉尼亚

本文主要是介绍维吉尼亚密码方阵,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



代码已上传到 GitHub —— Vigenere.java

维吉尼亚密码方阵


人们在恺撒移位密码的基础上扩展出多表密码,称为维吉尼亚密码。该方法最早记录在吉奥万·巴蒂斯塔·贝拉索( Giovan Battista Bellaso)于1553年所著的书《吉奥万·巴蒂斯塔·贝拉索先生的密码》

维吉尼亚密码方阵.jpg

第一行代表明文字母,第一列代表密钥字母,它的明码表后有26个密码表,每个表相对前一个发生一次移位

如果只用其中某一个进行加密,那么只是简单的恺撒移位密码。但用方阵中不同的行加密不同的字母,它就是一种强大的密码了

加密者可用第7行来加密第一个字母,再用第25行来加密第二个字母,然后根据第8行来加密第三个字母等

使用维吉尼亚密码


维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计

加密

  1. 确定密钥

    首先,和消息接收方需要在密钥上达成一致,加密解密都是同一个密钥,比如选用BIG

  2. 排列明文

    把明文转换为大写字母排列出来,对应着重复排列密钥,直到明文结尾

    明文:THE BUTCHER THE BAKER AND THE CANDLESTICK MAKER
    密钥:BIG BIGBIGB IGB IGBIG BIG BIG BIGBIGBIGBI GBIGB


  3. 加密明文

    然后,每一组的两个字母就成了我们的坐标。在维吉尼亚坐标图中分别横向纵向找出它们。横坐标和纵坐标的交点就是加密后的字母

    比如例子中的第一个字母是T,它下面是B,在维吉尼亚密码表中第一行找到T,第一列中找到B,所以得到的它们的交点就是U

    明文:THE BUTCHER THE BAKER AND THE CANDLESTICK MAKER
    密钥:BIG BIGBIGB IGB IGBIG BIG BIG BIGBIGBIGBI GBIGB
    密文:UPK CCZDPKS BNF JGLMX BVJ UPK DITETKTBODS SBSKS



解密

  1. 排列密文

    和加密一样,把密文排列出来,在下面对应着重复排列密钥

    密文:UPK CCZDPKS BNF JGLMX BVJ UPK DITETKTBODS SBSKS
    密钥:BIG BIGBIGB IGB IGBIG BIG BIG BIGBIGBIGBI GBIGB


  2. 解密密文

    解密就是加密的逆过程,比如第一个字母是U,下面是B,找到B开头的那一行,在该行中找到U,得到的明文字母就是那一列的开头字母T

    密文:UPK CCZDPKS BNF JGLMX BVJ UPK DITETKTBODS SBSKS
    密钥:BIG BIGBIGB IGB IGBIG BIG BIG BIGBIGBIGBI GBIGB
    明文:THE BUTCHER THE BAKER AND THE CANDLESTICK MAKER



破解维吉尼亚密码


确定密钥长度m

Kasiski测试法

Kasiski测试法是由Friedrich Kasiski于1863年给出了其描述,然而早在约1854年这一方法就由Charles Babbage首先发现

它主要基于这样一个事实:两个相同的明文段将加密成相同的密文段,它们的位置间距假设为δ,则δ≡0(mod m)。反过来,如果在密文中观察到两个相同的长度至少为3的密文段,那么将给破译者带来很大方便,因为它们实际上对应了相同的明文串

使用流程

搜索长度至少为3的相同的密文段,记下其离起始点的那个密文段的距离。假如得到如下几个距离δ₁,δ₂,...,那么,可以猜测m为这些δi的最大公因子的因子

使用实例
密钥:FORESTFORESTFORESTFORESTFOR
明文:better to do well than to say well
密文: GSKXWKYCUSOXQZKLSGYCJEQPJZC



第一个YC出现后到第二个YC的结尾一共有12个字母,那么密钥的长度应是12的约数1,2,3,4,6,12之中的一个

当密文很长的时候,可以找出几组重复的密文段,找出它们间距的相同约数,就是密钥长度

重合指数法

重合指数(Index of Coincidence)

x=x1x2...xn是一条n个字母的串,x的重合指数记为CI,定义为x中两个随机元素相同的概率

定义公式:

重合指数公式.png

常用公式:xi为字母的频数,L为密文的长度

常用公式.png

字母在英语文本中出现的概率:

字母在英文中出现的概率.png

对英语而言,根据上述的频率表,我们可以计算出英语文本的重合指数为P(A)^2 + P(B)^2+……+P(Z)^2 = 0.065

利用重合指数推测密钥长度的原理在于,对于一个由凯撒密码加密的序列,由于所有字母的位移程度相同,所以密文的重合指数应等于原文语言的重合指数

使用重合指数法

假设使用维吉尼亚密码加密的密文串为y=y1y2...yn。将串y分割成m个长度相等的子串,分别为y1,y2,...,ym,这样就可以以列的形式写出密文,组成一个m×(n/m)矩阵。矩阵的每一行对应于子串yi,1≤i≤m

举例来说

密文ABCDEABCDEABCDEABC

m=2分组,则每组为

1:A C E B D A C E B
组2:B D A C E B D A C


如果y1,y2,...,ym按如上方式构造,则m实际上就是密钥字的长度,每一组的CI值大约为0.065。另外,如果m不是密钥字的长度,那么子串yi看起来更为随机,因为它们是通过不同密钥以移位加密方式获得的。对于一个随机串,其重合指数为0.038

代码实现

// Friedman测试法确定密钥长度public int Friedman(String ciphertext) {int keyLength = 1; // 猜测密钥长度double[] Ic; // 重合指数double avgIc; // 平均重合指数ArrayList<String> cipherGroup; // 密文分组while (true) {Ic = new double[keyLength];cipherGroup = new ArrayList<>();avgIc = 0;// 1 先根据密钥长度分组for (int i = 0; i < keyLength; ++i) {StringBuilder tempGroup = new StringBuilder();for (int j = 0; i + j * keyLength < ciphertext.length(); ++j) {tempGroup.append(ciphertext.charAt(i + j * keyLength));}cipherGroup.add(tempGroup.toString());}// 2 再计算每一组的重合指数for (int i = 0; i < keyLength; ++i) {String subCipher = cipherGroup.get(i); // 子串HashMap<Character, Integer> occurrenceNumber = new HashMap<>(); // 字母及其出现的次数// 2.1 初始化字母及其次数键值对for (int h = 0; h < 26; ++h) {occurrenceNumber.put((char) (h + 65), 0);}// 2.2 统计每个字母出现的次数for (int j = 0; j < subCipher.length(); ++j) {occurrenceNumber.put(subCipher.charAt(j), occurrenceNumber.get(subCipher.charAt(j)) + 1);}// 2.3 计算重合指数double denominator = Math.pow((double) subCipher.length(), 2);for (int k = 0; k < 26; ++k) {double o = (double) occurrenceNumber.get((char) (k + 65));Ic[i] += o * (o - 1);}Ic[i] /= denominator;}// 3 判断退出条件,重合指数的平均值是否大于0.065for (int i = 0; i < keyLength; ++i) {avgIc += Ic[i];}avgIc /= (double) keyLength;if (avgIc >= 0.06) {break;} else {keyLength++;}} // while--end// 打印密钥长度,分组,重合指数,平均重合指数System.out.println("密钥长度为:" + String.valueOf(keyLength));System.out.println("\n密文分组及其重合指数为:");for (int i = 0; i < keyLength; ++i) {System.out.println(cipherGroup.get(i) + "   重合指数: " + Ic[i]);}System.out.println("\n平均重合指数为: " + String.valueOf(avgIc));return keyLength;}// Friedman--end

 

确定密钥

拟重合指数测试法

在知道了密钥长度n以后,就可将密文分解为n组,每一组都是一个凯撒密码,然后对每一组用字母频度分析进行解密,和在一起就能成功解密凯撒密码

首先对子密文段重各个字母的频率进行统计(记为fi, i∈a – z),查看字母频率分布统计概率表(记pi),计算子密文段长度为n,使用公式

拟重合指数公式

计算出M0,然后对子密文段移位25次,同样按照上述方法求出M1 — M25的值

根据重合指数的定义知:一个有意义的英文文本,M ≈0.065,所以找出M值接近0.065的移位数,就是秘钥中的对应字母

代码实现

 
// 再次使用重合指数法确定密钥public void decryptCipher(int keyLength, String ciphertext) {int[] key = new int[keyLength];ArrayList<String> cipherGroup = new ArrayList<>();double[] probability = new double[]{0.082, 0.015, 0.028, 0.043, 0.127, 0.022, 0.02, 0.061, 0.07, 0.002, 0.008,0.04, 0.024, 0.067, 0.075, 0.019, 0.001, 0.06, 0.063, 0.091, 0.028, 0.01, 0.023, 0.001, 0.02, 0.001};// 1 先根据密钥长度分组for (int i = 0; i < keyLength; ++i) {StringBuilder temporaryGroup = new StringBuilder();for (int j = 0; i + j * keyLength < ciphertext.length(); ++j) {temporaryGroup.append(ciphertext.charAt(i + j * keyLength));}cipherGroup.add(temporaryGroup.toString());}// 2 确定密钥for (int i = 0; i < keyLength; ++i) {double MG; // 重合指数int flag; // 移动位置int g = 0; // 密文移动g个位置HashMap<Character, Integer> occurrenceNumber; // 字母出现次数String subCipher; // 子串while (true) {MG = 0;flag = 65 + g;subCipher = cipherGroup.get(i);occurrenceNumber = new HashMap<>();// 2.1 初始化字母及其次数for (int h = 0; h < 26; ++h) {occurrenceNumber.put((char) (h + 65), 0);}// 2.2 统计字母出现次数for (int j = 0; j < subCipher.length(); ++j) {occurrenceNumber.put(subCipher.charAt(j), occurrenceNumber.get(subCipher.charAt(j)) + 1);}// 2.3 计算重合指数for (int k = 0; k < 26; ++k, ++flag) {double p = probability[k];flag = (flag == 91) ? 65 : flag;double f = (double) occurrenceNumber.get((char) flag) / subCipher.length();MG += p * f;}// 2.4 判断退出条件if (MG >= 0.055) {key[i] = g;break;} else {++g;}} // while--end} // for--end// 3 打印密钥StringBuilder keyString = new StringBuilder();for (int i = 0; i < keyLength; ++i) {keyString.append((char) (key[i] + 65));}System.out.println("\n密钥为: " + keyString.toString());// 4 解密StringBuilder plainBuffer = new StringBuilder();for (int i = 0; i < ciphertext.length(); ++i) {int keyFlag = i % keyLength;int change = (int) ciphertext.charAt(i) - 65 - key[keyFlag];char plainLetter = (char) ((change < 0 ? (change + 26) : change) + 65);plainBuffer.append(plainLetter);}System.out.println("\n明文为:\n" + plainBuffer.toString().toLowerCase());}

算法运行实例


密文

KCCPKBGUFDPHQTYAVINRRTMVGRKDNBVFDETDGILT
XRGUDDKOTFMBPVGEGLTGCKQRACQCWDNAWCRXI
ZAKFTLEWRPTYCQKYVXCHKFTPONCQQRHJVAJUWE
TMCMSPKQDYHJVDAHCTRLSVSKCGCZQQDZXGSFRL
SWCWSJTBHAFSIASPRJAHKJRJUMVGKMITZHFPDISP
ZLVLGWTFPLKKEBDPGCEBSHCTJRWXBAFSPEZQNR
WXCVYCGAONWDDKACKAWBBIKFTIOVKCGGHJVLNHI
FFSQESVYCLACNVRWBBIREPBBVFEXOSCDYGZWPFD
TKFQIYCWHJVLNHIQIBTKHJVNPIST

运行结果

密钥长度为:6密文分组及其重合指数为:
KGQNGVGGTGCQWAWQHNJEPJTKQFWAPJGHPWKCTAQVNCIVJFVNIVCPQJQJT   重合指数: 0.061557402277623886
CUTRRFIUFEKCCKRKKCVTKVRCDRSFRRKFZTEEJFNYWKKKVFYVRFDFIVIV   重合指数: 0.08227040816326531
CFYRKDLDMGQWRFPYFQAMQDLGZLJSJJMPLFBBRSRCDAFCLSCREEYDYLBN   重合指数: 0.04846938775510204
PDATDETDBLRDXTTVTQJCDASCXSTIAUIDVPDSWPWGDWTGNQLWPXGTCNTP   重合指数: 0.06377551020408163
KPVMNTXKPTANILYXPRUMYHVZGWBAHMTILLPHXEXAKBIGHEABBOZKWHKI   重合指数: 0.042091836734693876
BHIVBDROVGCAZECCOHWSHCSQSCHSKVZSGKGCBZCOABOHISCBBSWFHIHS   重合指数: 0.07206632653061225平均重合指数为: 0.061705145277563156密钥为: CRYPTO明文为:
i learned how to calculate the amount of paper needed for a 
room when i was at school you multiply the square foot age 
of the walls by the cubic contents of the floor and ceiling 
combined and double it you then allow half the total for 
openings such as windows and doors then you allow the 
other half for matching the pattern then you double the 
whole thing again to give a margin of error and then you 
order the paper

这篇关于维吉尼亚密码方阵的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/376206

相关文章

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

华为OD机试真题-学生方阵-2024年OD统一考试(E卷)

题目描述 学校组织活动,将学生排成一个矩形方阵。 请在矩形方阵中找到最大的位置相连的男生数量。这个相连位置在一个直线上,方向可以是水平的,垂直的,成对角线的或者呈反对角线的。 注:学生个数不会超过10000 输入描述 输入的第一行为矩阵的行数和列数, 接下来的 n行为矩阵元素,元素间用""分隔。 输出描述 输出一个整数,表示矩阵中最长的位

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密 可以将表情,动物,水果,表情,手势,猫语,兽语,狗语,爱语,符号,数字,字母,加密和解密 可以将文字、字母、数字、代码、标点符号等内容转换成新的文字形式,通过简单的文字以不同的排列顺序来表达不同的内容 源码截图: https://www.httple.net/152649.html

mysql导出导入数据和修改登录密码

导出表结构: mysqldump -uroot -ppassword -d dbname tablename>db.sql; 导出表数据: mysqldump -t dbname -uroot -ppassword > db.sql 导出表结构和数据(不加-d): mysqldump -uroot -ppassword dbname tablename > db.sql;

Ubuntu 环境下ssh的安装、使用以及免密码登录

以两台机器为例:     A12.12.10.11B12.12.10.13 安装: Ubuntu默认安装了ssh客户端,只需要在被登录的机器上安装ssh服务器即可: $ sudo apt-get install openssh-server     启动ssh服务器: $ sudo /etc/init.d/ssh start 查看是否启动成功: $ ps -ef |grep

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录(失败记录)

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录 这次是装实体机,一次失败的尝试。。。 名称型号CPUIntel Xeon E5-2673 V3GPURTX 3060 mobile 安装的时候不要选install third-party software for graphics and Wi-fi hardware and additional media

oracle密码维护

查看密码是否可以重复使用 SQL> select PROFILE,RESOURCE_NAME,LIMIT from dba_profiles where profile='DEFAULT' and resource_type ='PASSWORD'; PROFILE                        RESOURCE_NAME                    LIMIT ----

【网络安全】古典密码体制概述

1. 古典密码体制概述 1.1 定义与历史背景 古典密码体制是指在计算机科学和信息安全技术出现之前的传统加密方法。这些方法主要包括替换和易位两种基本形式。古典密码体制的特点是简单、易用,但安全性不高,容易被破解。在古代,人们使用纸、笔或简单的器械来实现加密和解密操作。 定义:古典密码体制是基于简单数学运算和文字替换的加密方法,包括替代密码和置换密码两大类。历史背景:古典密码的使用可以追溯到古

vsftpd配置用户和密码让其他客户端连接

一、第一个主机:vsftpd下载及配置 前置准备: #卸载防火墙yum -y remove firewalld#为了不让防火墙有影响,iptables配置也清空iptables -Fvim /etc/selinux/confSELINUX=disabled #主要是把它改为disabled或者permissiveSELINUXTYPE=targeted#重启linux让selin