目录
字母表中每一个字母都对应着一个数字,从A~ Z依次是0~25,给定一个明文与密文,假设明文是showmaker,密钥是bde,则密钥三个字母对应的三个数字分别是1,3,4,而密钥的长度为3,我们以每组3个字符的长度将明文分为 sho wma ker三组,其中每组的第一个字母s w k需要加上1,也就是向后取一个字母,得到t x l,而每组的第二个字母需要+3,每组的第三个字母+4,其中,若加密得到的字母超出z(即25),则从a开始重新计数,也就是取26的模,明文全部加密按顺序得到的字符串即为密文。
明文:showmaker
密钥:bde
密文:tksxpelhv
维吉尼亚密码的加密过程较为简单,只需要通过循环将明文字母的Unicode码加上相应的数字即可实现,要注意的是输入的明文中可能存在大小写与标点符号,需要将标点符号剔除,并将其统一转化为大写形式或者小写形式。
所以主要有以下步骤:
1、获取密钥长度与密钥中字母所对应的0~25数字。
2、剔除明文中的标点符号并统一大小写
3、通过循环将所有明文字母的Unicode码加上相应的数字(mod 26)
str = input("请输入密钥:")
length = len(str)
str.lower() #将输入字母全部转换为小写
list_cipher = [] #创建空列表,用于存放密钥对应的数字
#下面将将密钥对应的数字输入到列表list_cipher中
for i in str:
no_cipher = ord(i) - ord('a')
list_cipher.append(no_cipher)
plaintext_path = input("请输入明文所在txt文件的路径:")
#下面获取明文
f_1 = open(plaintext_path,'r')
plaintext_0 = f_1.read()
f_1.close()
plaintext = ''
#下面将一个个字符的Unicode码进行比对,来达到去除标点符号的目的
for i in plaintext_0:
if (ord('a') <= ord(i) and ord('z') >= ord(i)) or (ord('A') <= ord(i) and ord('Z') >= ord(i)):
plaintext += i
plaintext = plaintext.lower()
count = 0
cipher = ''
#下面是加密程序
while count <= (len(plaintext)-1):
for i in range(length):
if count + i <= (len(plaintext)-1):
cipher_word = chr((ord(plaintext[count+i]) + list_cipher[i] - ord('a')) % 26 + ord('a'))
cipher += cipher_word
count += length
f_2 = open('C:\\Users\\辉夜大小姐\\PycharmProjects\\pythonProject\\cipher.txt','w')
for i in range(len(cipher)):
f_2.write(cipher[i])
f_2.close()
str = input("请输入密钥:")
length = len(str)
str.lower() #将输入字母全部转换为小写
list_cipher = [] #创建空列表,用于存放密钥对应的数字
#下面将将密钥对应的数字输入到列表list_cipher中
for i in str:
no_cipher = ord(i) - ord('a')
list_cipher.append(no_cipher)
先输入密钥,假设我输入的密钥是crypto。
length的值即为密钥长度,将密钥转化为小写,每个字母与字母a的Unicode码的差即为其所对应的数字,依次保存在列表list_cipher中。
plaintext_path = input("请输入明文所在txt文件的路径:")
#下面获取明文
f_1 = open(plaintext_path,'r')
plaintext_0 = f_1.read()
f_1.close()
plaintext = ''
#下面将一个个字符的Unicode码进行比对,来达到去除标点符号的目的
for i in plaintext_0:
if (ord('a') <= ord(i) and ord('z') >= ord(i)) or (ord('A') <= ord(i) and ord('Z') >= ord(i)):
plaintext += i
plaintext = plaintext.lower()
将明文写在一个txt文件中,如下图。

输入该txt文件所在的路径,而后将内容读到plaintext_0中,将plaintext_0中的所有字符遍历一遍,留下Unicode码在a~z之间或者A到Z之间的字符并保存在plaintext中,达到剔除标点符号的目的,再通过lower函数将其全部小写,方便后续的加密过程。
count = 0
cipher = ''
#下面是加密程序
while count <= (len(plaintext)-1):
for i in range(length):
if count + i <= (len(plaintext)-1):
cipher_word = chr((ord(plaintext[count+i]) + list_cipher[i] - ord('a')) % 26 + ord('a'))
cipher += cipher_word
count += length
f_2 = open('C:\\Users\\辉夜大小姐\\PycharmProjects\\pythonProject\\cipher.txt','w')
for i in range(len(cipher)):
f_2.write(cipher[i])
f_2.close()
以length(密钥长度)进行for循环,通过Unicode码的转换将明文转化为密文,并写入到另一个txt文件中。我们运行一遍代码看看cipher.txt。

可以看到txt中已经有了写入的密文,如果该txt文件中原本有内容,那也会将原内容进行覆盖。
我们先看一个表
| 字 母 | 概 率 | 字 母 | 概 率 |
|---|---|---|---|
| A | 0.082 | N | 0.067 |
| B | 0.015 | O | 0.075 |
| C | 0.028 | P | 0.019 |
| D | 0.043 | Q | 0.001 |
| E | 0.127 | R | 0.060 |
| F | 0.022 | S | 0.063 |
| G | 0.020 | T | 0.091 |
| H | 0.061 | U | 0.028 |
| I | 0.070 | V | 0.010 |
| J | 0.002 | W | 0.023 |
| K | 0.008 | X | 0.001 |
| L | 0.040 | Y | 0.020 |
| M | 0.024 | Z | 0.001 |
这是从众多小说、杂志和报纸上搜集统计出的26个字母出现的相对概率。
本次代码中我使用重合指数法来实现维吉尼亚密码的解密。
用 f 0 , f 1 , … f 25 f_0,f_1,…f_{25} f0,f1,…f25来表示A,B,C,……Z出现的频数,则在长度为n的字母串中随机取两个字母,取到相同字母的概率为 I c ( x ) = ∑ i = 0 25 f i ( f i − 1 ) n ( n − 1 ) I_c(x)={{\sum_{i=0}^{25}f_i(f_i-1)}\over{n(n-1)}} Ic(x)=n(n−1)∑i=025fi(fi−1),表1.1中的数据可得出 I c ( x ) ≈ 0.065 I_c(x)≈0.065 Ic(x)≈0.065。
假设长度为n的密文串为 Y = y 1 y 2 … y n Y=y_1y_2…y_n Y=y1y2…yn。将其分割为m组长度相等的子串,具体如下。
Y 1 = y 1 y m + 1 y 2 m + 1 … Y_1=y_1y_{m+1}y_{2m+1}… Y1=y1ym+1y2m+1…
Y 2 = y 2 y m + 2 y 2 m + 2 … Y_2=y_2y_{m+2}y_{2m+2}… Y2=y2ym+2y2m+2…
┆ ┆ ┆
Y m = y m y 2 m y 3 m … Y_m=y_my_{2m}y_{3m}… Ym=ymy2my3m…
如果m是密钥字的长度,那么每一个 I c ( Y i ) I_c(Y_i) Ic(Yi)的值会在0.065附近。
所以我们可以通过循环来从m = 1开始尝试,一直到选定的一个值(比如m = 10),找出其中 I c ( Y ) I_c(Y) Ic(Y)最接近于0.065时m的值,此时m的值最有可能是密钥的长度。
得到密钥长度后,定义公式 M g = ∑ i = 0 25 p i f i + g n ′ M_g=\sum_{i=0}^{25}{p_if_{i+g}\over{n'}} Mg=∑i=025n′pifi+g(n’为每个子串的长度)( 0 ≤ g ≤ 25 0≤g≤25 0≤g≤25,代表着26个字母)
若 g = k i g=k_i g=ki,即 g g g对应密钥当前位的正确字母,则应该有 M g ≈ 0.065 M_g≈0.065 Mg≈0.065。
通过遍历0~25,得到 M g M_g Mg最接近0.065时的 g g g的值,重复该过程m次,而后将得到的数字全部转化为字母顺序排列,即可得到密钥。
cipher_path = input("请输入密文所在txt文件的路径:")
f = open(cipher_path)
cipher = f.read()
f.close()
cipher = cipher.lower()
cipher = ",".join(cipher)
list_cipher = cipher.split(",") #将密文中的每个字母转化为列表中的元素
#下面这个函数用于记录字母在列表中出现的频数
def count_f(unicode,list):
length = len(list)
count = 0
for i in range(length):
if chr(unicode) == list[i]:
count = count + 1
return count
#该函数用于将密文列表分为m组,每一组n个
def list_M(m,n):
list_m = []
for i in range(m):
for j in range(n):
list_m.append(list_cipher[i + j * m])
return list_m
#下面来求密钥字长度m
for m in range(1,10):
n = int((len(list_cipher) - len(list_cipher) % m) / m) #n为每一组的个数,若无法平分则舍弃最后的几个密文
list_m = list_M(m, n)
#得到的列表list_m每n个为一组,共m组
#下面求每一组中各个字母的出现频数
list_I = [] #用于保存每一组的重合指数
for i in range(m):
list_f = [] # 用于记录各个字母出现的频数
for j in range(26):
unicode_j = ord('a') + j
list_f.append(count_f(unicode_j, list_m[i * n:(i * n + n)]))
#下面求每一组的重合指数
I = 0
for j in range(26):
I = I + (list_f[j]*(list_f[j]-1))/(n * (n - 1))
list_I.append(I)
#下面求平均重合指数以及它与0.065的差值
sum = 0
for i in range(m):
sum = sum + list_I[i]
avg_I = sum / m
difference = abs(avg_I-0.065)
if m == 1:
t = difference
k = 1
elif m != 1:
if difference <= t: #作比较,若这一次的差值小于上一次的差值,说明这一次的重合指数更接近0.065,循环结束后得到的k即为密钥字长度
t = difference
k = m
#得到了密钥的长度,下面来求密钥
n = int((len(list_cipher) - len(list_cipher) % k) / k)
list_m = list_M(k, n)
list_secret = []
list_usual = [0.082,0.015,0.028,0.043,0.127,0.022,0.020,0.061,0.070,0.002,0.008,0.040,0.024,0.067,0.075,0.019,0.001,0.060,0.063,0.091,0.028,0.010,0.023,0.001,0.020,0.001]
for i in range(k):
list_f = [] # 用于记录各个字母出现的频数
for j in range(26):
unicode_j = ord('a') + j
list_f.append(count_f(unicode_j, list_m[i * n:(i * n + n)]))
for g in range(26):
sum = 0
for p in range(26):
sum = sum + list_usual[p]*list_f[(p+g)%26]
M = abs((sum / n) - 0.065)
if g == 0:
t = M
secret = 0
elif g != 0:
if M <= t:
t = M
secret = g
list_secret.append(secret)
list_str = []
for i in range(k):
list_str.append(chr(ord('a') + list_secret[i]))
str = ''.join(list_str)
print(str)
list_str.append(chr(ord('a') + list_secret[i]))
str = ''.join(list_str)
print(str)
cipher_path = input("请输入密文所在txt文件的路径:")
f = open(cipher_path)
cipher = f.read()
f.close()
cipher = cipher.lower()
cipher = ",".join(cipher)
list_cipher = cipher.split(",") #将密文中的每个字母转化为列表中的元素
读取密文所在txt文件中的内容,并将其全部转化为小写后保存在列表中,每个字母均为一个单独的元素
#下面这个函数用于记录字母在列表中出现的频数
def count_f(unicode,list):
length = len(list)
count = 0
for i in range(length):
if chr(unicode) == list[i]:
count = count + 1
return count
#该函数用于将密文列表分为m组,每一组n个
def list_M(m,n):
list_m = []
for i in range(m):
for j in range(n):
list_m.append(list_cipher[i + j * m])
return list_m
两个函数的编写,用于后续使用
count_f函数为输入一个字母的Unicode码与一个列表,而后返回该字母在此列表中出现的频数。
list_M函数用于将密文分组。
#下面来求密钥字长度m
for m in range(1,10):
n = int((len(list_cipher) - len(list_cipher) % m) / m) #n为每一组的个数,若无法平分则舍弃最后的几个密文
list_m = list_M(m, n)
#得到的列表list_m每n个为一组,共m组
#下面求每一组中各个字母的出现频数
list_I = [] #用于保存每一组的重合指数
for i in range(m):
list_f = [] # 用于记录各个字母出现的频数
for j in range(26):
unicode_j = ord('a') + j
list_f.append(count_f(unicode_j, list_m[i * n:(i * n + n)]))
#下面求每一组的重合指数
I = 0
for j in range(26):
I = I + (list_f[j]*(list_f[j]-1))/(n * (n - 1))
list_I.append(I)
#下面求平均重合指数以及它与0.065的差值
sum = 0
for i in range(m):
sum = sum + list_I[i]
avg_I = sum / m
difference = abs(avg_I-0.065)
if m == 1:
t = difference
k = 1
elif m != 1:
if difference <= t: #作比较,若这一次的差值小于上一次的差值,说明这一次的重合指数更接近0.065,循环结束后得到的k即为密钥字长度
t = difference
k = m
这里m的循环我只写了(1,10),只进行到9,也就是说只能破解9位以下的密钥。
由于密文的长度n不一定每一次都能整除m,所以直接舍弃最后一部分,来保证可以将其分为长度相等的m组。
list_m列表的顺序为[ y 1 , y m + 1 , … y ( n − 1 ) ∗ m + 1 , y 2 … y m n y_1,y_{m+1},…y_{(n-1)*m+1},y_2…y_{mn} y1,ym+1,…y(n−1)∗m+1,y2…ymn],即依次为 Y 1 , Y 2 … Y m Y_1,Y_2…Y_m Y1,Y2…Ym。
list_f列表的顺序与list_m相同,后者的元素是密文中的字母,前者的元素是其对应字母的在每一组中的出现频数(例如字母a在 Y 1 Y_1 Y1中的出现频数)
list_I中记录的依次是 Y 1 , Y 2 , … Y m Y_1,Y_2,…Y_m Y1,Y2,…Ym的重合指数。
而后取出list_I中的元素求总的平均重合指数,并求与0.065的差值,每一次m与前一次m的差值进行比较,用k保留差值较小时的m,循环结束后得到的k即为密钥的长度。
#得到了密钥的长度,下面来求密钥
n = int((len(list_cipher) - len(list_cipher) % k) / k)
list_m = list_M(k, n)
list_secret = [] #用于保存密钥字母对应的数字
list_usual = [0.082,0.015,0.028,0.043,0.127,0.022,0.020,0.061,0.070,0.002,0.008,0.040,0.024,0.067,0.075,0.019,0.001,0.060,0.063,0.091,0.028,0.010,0.023,0.001,0.020,0.001]
for in range(k):
list_f = [] # 用于记录各个字母出现的频数
for j in range(26):
unicode_j = ord('a') + j
list_f.append(count_f(unicode_j, list_m[i * n:(i * n + n)]))
for g in range(26):
sum = 0
for p in range(26):
sum = sum + list_usual[p]*list_f[(p+g)%26]
M = abs((sum / n) - 0.065)
if g == 0:
t = M
secret = 0
elif g != 0:
if M <= t:
t = M
secret = g
list_secret.append(secret)
list_str = []
for i in range(k):
list_str.append(chr(ord('a') + list_secret[i]))
str = ''.join(list_str)
print(str)
此时密钥长度k已经得到,利用list_M函数来进行分成k组。
list_usual中的元素依次为上面表中A~Z的出现概率,用其进行 M g M_g Mg的计算,并与0.065进行比较,将最靠近0.065时的 g g g值保存在list_secret列表中,最后利用Unicode码转化为字母并保存在字符串str中并打印出str,即密钥。
前面我们利用加密程序对明文加密得到了密文,现在我们将得到的密文在解密程序中运行来看看结果。

可以看到密钥完全正确。
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决
我需要尝试一些AES片段。我有一些密文c和一个keyk。密文已使用AES-CBC加密,并在前面加上IV。不存在填充,纯文本的长度是16的倍数。所以我这样做:aes=OpenSSL::Cipher::Cipher.new("AES-128-CCB")aes.decryptaes.key=kaes.iv=c[0..15]aes.update(c[16..63])+aes.final它工作得很好。现在我需要手动执行CBC模式,所以我需要单个block的“普通”AES解密。我正在尝试这个:aes=OpenSSL::Cipher::Cipher.new("AES-128-ECB")aes.dec