• 'real'词频分析


    写下来想法来自于无聊时写的代码.https://cryptopals.com/sets/1/challenges/3

    The hex encoded string:

    1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
    ... has been XOR'd against a single character. Find the key, decrypt the message.

    You can do this by hand. But don't: write code to do it for you.

    How? Devise some method for "scoring" a piece of English plaintext. Character frequency is a good metric. Evaluate each output and choose the one with the best score.

    单字节密码加密

    我们知道有一种简单的加密.真的很简单.

    我给出的方案是这样定义的:

    [Scheme := <Gen,Enc,Dec> ]

    [Gen : key= random([0,1,..255]) ]

    [Enc : ciphertext = xor(plaintext,key*plaintext.len) ]

    [Dec: plaintext = xor(ciphertext,key*ciphertext.len) ]

    攻击方案

    很简单,搜索一下密钥空间,看看哪些有意义.就可以解决了.但是不够高效.指的是我们还需要看256次,如果要解密的很多,会很麻烦.

    过滤

    最简单的就是过滤非法字符,白名单可以是[0-9a-zA-Z'! ?s],这样可以过滤一些不合法的结果,直接减少了工作量.但是遇到大量混淆过的问题---指定是很多虽然字符合法但是不是英文语言的情况,却又无能为力了.

    频率分析

    我记得我上密码学的时候,老师讲过一种词频分析的攻击方法.这里的方法的含义就是这样.对每个可能的字符串进行合法判断,给出一个可能是英文句子的分数.然后每次只要最大的分数.再加上之前的白名单过滤.我们就可以快速判断大量数据中的可读的字符串.

    实现

    获得一份英文单词频率分布表.({x_a,x_b,..,x_z,x_{space}}),对于需要判定的串(w = w_1...w_n),最初始让(score = 0),分数为0.

    对串中每个字符,如果(w_i)在分布表中,那么就(score = score + x_{w_i}),如果不在分布表中(score = score - 0.05).

    代码如下:

    def frequencyScore(b:bytes)->int:
        '''
        frequency data: https://web.archive.org/web/20170918020907/http://www.data-compression.com/english.html
        return a frequencyScore for a bytes string.
        '''
        score = 0
        letter_freqs = {
                'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339,
                'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881,
                'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094,
                'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490,
                'm': 0.0202124, 'n': 0.0564513, 'o': 0.0596302,
                'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563,
                's': 0.0515760, 't': 0.0729357, 'u': 0.0225134,
                'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692,
                'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182}
    
        for ele in b:
            if (ele>ord('a') and ele<ord('z')) or (ele>ord('A') and ele<ord('Z')) or ele==ord(' '):
                score += letter_freqs[chr(ele).lower()]
            else:
                score -= 0.05
        return score
    

    这是完整的代码:https://github.com/zhuowangy2k/code-snippet/blob/master/frequency-single-xor/frequency-single-xor.py

  • 相关阅读:
    Scons 三
    Scons 二
    vs code插件
    Scons一
    实例演示 C# 中 Dictionary<Key, Value> 的检索速度远远大于 hobbyList.Where(c => c.UserId == user.Id)
    ASP.NET Core 如何用 Cookie 来做身份验证
    如何设计出和 ASP.NET Core 中 Middleware 一样的 API 方法?
    小记编程语言的设计
    解决 VS2019 打开 edmx 文件时没有 Diagram 视图的 Bug
    一款回到顶部的 jQuery 插件,支持 Div 中的滚动条回到顶部
  • 原文地址:https://www.cnblogs.com/zhuowangy2k/p/10862814.html
Copyright © 2020-2023  润新知