Python 游乐场山坡裂缝

Python 游乐场山坡裂缝,python,algorithm,cryptography,hill-climbing,Python,Algorithm,Cryptography,Hill Climbing,我正在编写一个python脚本来破解playfair密码,只使用密文。 首先,我生成大约30-100个解密密钥,并在密文上运行它们,根据每个密钥的有向图频率对它们进行排序。在下一代/迭代中,我复制得分最高的。然后对它们进行变异(字母在5x5网格中交换位置)并重新添加到下一个迭代中,然后再次进行排序,依此类推 我注意到脚本经常会找到一个局部最大值——一个给出类似分布的键,但不是真正的交易。我认为解决这个问题的办法是对密钥的总体引入更多的变化(在脚本结束时,所有密钥几乎都是相同的) 我试图通过在每一

我正在编写一个python脚本来破解playfair密码,只使用密文。 首先,我生成大约30-100个解密密钥,并在密文上运行它们,根据每个密钥的有向图频率对它们进行排序。在下一代/迭代中,我复制得分最高的。然后对它们进行变异(字母在5x5网格中交换位置)并重新添加到下一个迭代中,然后再次进行排序,依此类推

我注意到脚本经常会找到一个局部最大值——一个给出类似分布的键,但不是真正的交易。我认为解决这个问题的办法是对密钥的总体引入更多的变化(在脚本结束时,所有密钥几乎都是相同的)

我试图通过在每一代中添加两个完全随机的键来实现它,但它们几乎立即被消除。有什么更好的方法?我也想过类似模拟退火的策略,但不知道它们会有多大帮助

编辑:请求的示例密文(键:playfair示例)

如图所示,我公司将在第九届会议上宣布我公司将在第十五届会议上宣布我公司将在第五届会议上宣布我公司将在第六届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第五届会议上宣布我公司将在第六届会议上宣布我公司将在第六届会议上宣布我公司的决定在本财年内,所有设备均为新的tx zb bm kn ul bn ar km uz fo ka ro do gp lo kv dm ml qe zi lo rk pr ad xl tx zb le nv oc py dr lo ca le dx xa mo PRO yp yp DOC dk zb作为kv ix ol pr dr oq dr oq dr OB dr gb eo ak vg xe DOF re zb pv nl cr DOA ad iu dm REE dm eo qm am am am am PUS xl nl nv kz qn oq yg dm df pb yg df pb yf yf yf yf vk pz yp zb gd yp yf yp yf yf yp pz yp yp zb pz Yvq vo vk pr kz ro


如果我没看错你的问题,你改变了你这一代,但你没有重组它。也许你可以这样做:

  • 第0代是随机密钥
  • 选择n个排名最高的键,其余的都会消失
  • 将幸存者杂交。重组时低百分比突变
  • 冲洗并重复
  • 重组可能是这样的:

  • 父母是A和B,他们产生n个后代

  • 对于每个子代,选择0应用于加密的爬山算法原理如下:

  • 随机制作一个键(ramdom制作一个25字符的字母表),并根据您的有向图评分确定适合度。称之为“家长”
  • 对父项进行一些更改,以生成一个“子”键(5x5网格键表中的随机交换并不是那么糟糕),并使用有向图评分函数测量其适合性
  • 如果孩子比父母更健康,就让孩子 新的父母,抛弃旧的
  • 回到(2),除非在过去1000年中没有任何改进 在这种情况下的更改返回到(1)
  • 这是避免在有向图评分函数的局部最大值中被阻塞的方法

    如果你想得到比爬山更好的结果,你必须开发一个模拟退火算法。此外,基于三叉图或4-gram的评分函数具有较少的局部最大值。 如果您想更快地破解它,您应该从python迁移到C/C++

    HillClimbing和模拟退火算法可用于破解Playfair密码以及所有其他基于5*5网格的密码,也可用于破解简单替换密码和Vigener密码

    Playfair密码的一个重要特点是它很弱:5x5网格的所有循环水平或垂直排列都是等效密钥。因此,该密码的algos收敛速度更快

    要制作父字母表,请使用以下命令:

    alpha='ABCDEFGHIKLMNOPQRSTUVWXYZ'
    used=[0]*25;parent=['']*25
    for i in range(25):
        j=randrange(25)
        while used[j]:j=randrange(25)
        parent[i]=alpha[j];used[j]=1
    
    playfair解密功能:

    def DEplayfair(a,key):
    l=[];order={}
    for k in range(25):order[key[k]]=k
    for i in range(0,len(a),2):
        ord1=order[a[i]]
        raw1=ord1//5
        col1=ord1%5
        ord2=order[a[i+1]]
        raw2=ord2//5
        col2=ord2%5
        if raw1==raw2:
            l.append(key[5*raw1 + (col1 + 4)%5])
            l.append(key[5*raw2 + (col2 + 4)%5])
        elif col1==col2:
            l.append(key[col1 + 5*((raw1 + 4)%5)])
            l.append(key[col2 + 5*((raw2 + 4)%5)])
        else:
            l.append(key[5*raw1 + col2])
            l.append(key[5*raw2 + col1])
    return ''.join(l)
    
    对于SA算法,您可以在以下内容中找到SA的基本原理:

    Playfair密码在二战期间被美国海岸警卫队使用,历史上有一个著名的Playfair密码:


    PS:playfair密码示例中的主要角色的名字是Alice。

    您能提供一些cyphertext示例吗?事实上,您是正确的,我没有重新组合任何密钥,但是playfair密钥是5x5网格,没有重复任何字符(基本上是置换),不幸的是A[:x]+B[x:y]+A[y:]不起作用,使用python的pickle模块,它是如何起作用的?我不明白15x1是如何发挥作用的25而不是15。如果你不想重组,就不要。
    def DEplayfair(a,key):
    l=[];order={}
    for k in range(25):order[key[k]]=k
    for i in range(0,len(a),2):
        ord1=order[a[i]]
        raw1=ord1//5
        col1=ord1%5
        ord2=order[a[i+1]]
        raw2=ord2//5
        col2=ord2%5
        if raw1==raw2:
            l.append(key[5*raw1 + (col1 + 4)%5])
            l.append(key[5*raw2 + (col2 + 4)%5])
        elif col1==col2:
            l.append(key[col1 + 5*((raw1 + 4)%5)])
            l.append(key[col2 + 5*((raw2 + 4)%5)])
        else:
            l.append(key[5*raw1 + col2])
            l.append(key[5*raw2 + col1])
    return ''.join(l)