zoukankan      html  css  js  c++  java
  • cryptopals S1-6

    题目:

    https://cryptopals.com/sets/1/challenges/6

    思路:

    Here's how:

    1. Let KEYSIZE be the guessed length of the key; try values from 2 to (say) 40.
    2. Write a function to compute the edit distance/Hamming distance between two strings. The Hamming distance is just the number of differing bits. The distance between:
      this is a test
      and
      wokka wokka!!!
      is 37. Make sure your code agrees before you proceed.
    3. For each KEYSIZE, take the first KEYSIZE worth of bytes, and the second KEYSIZE worth of bytes, and find the edit distance between them. Normalize this result by dividing by KEYSIZE.
    4. The KEYSIZE with the smallest normalized edit distance is probably the key. You could proceed perhaps with the smallest 2-3 KEYSIZE values. Or take 4 KEYSIZE blocks instead of 2 and average the distances.
    5. Now that you probably know the KEYSIZE: break the ciphertext into blocks of KEYSIZE length.
    6. Now transpose the blocks: make a block that is the first byte of every block, and a block that is the second byte of every block, and so on.
    7. Solve each block as if it was single-character XOR. You already have code to do this.
    8. For each block, the single-byte XOR key that produces the best looking histogram is the repeating-key XOR key byte for that block. Put them together and you have the key.

    解:

    def mdecode(x, key):
        y = bytearray([ord(x[i]) ^ ord(key[i % len(key)]) for i in range(len(x))]).hex()
        return y
    
    
    def calc_bit_diff(s1, s2):
        def calc_bit_diff_sub(i1, i2):
            cnt = 0
            for i in range(8):
                if (1<<i) & (i1 ^ i2) != 0:
                    cnt += 1
            return cnt
        ans = 0
        for i in range(len(s1)):
            ans += calc_bit_diff_sub(ord(s1[i]), ord(s2[i]))
        return ans
    
    
    def calc_bit_diff2(s1, s2):
        def calc_bit_diff_sub(i1, i2):
            cnt = 0
            for i in range(8):
                if (1<<i) & (i1 ^ i2) != 0:
                    cnt += 1
            return cnt
        ans = 0
        for i in range(len(s1)):
            ans += calc_bit_diff_sub(s1[i], s2[i])
        return ans
        
    import base64
    with open("f:\6.txt") as fin:
        txt = "".join([line.strip() for line in fin.readlines()])
        bx = base64.b64decode(txt)
        
    for keysz in range(2, 40):
        print(keysz, calc_bit_diff2(bx[:keysz], bx[keysz: 2 * keysz]) * 1.0 / keysz, sum([calc_bit_diff2(bx[keysz * i:keysz * i + keysz], bx[: keysz]) for i in range(10)]) * 1.0 / keysz) 
        
    
    def try_solve(barr):
        legal_chars = "01234567890abcdefghijklmnopgrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ ,.?!~'><@
    #
    +=-*`_^)(:;"[]{}\%$&|Jjq/"
        ans = []
        for i in range(256):
            y = [chr(i^sx) for sx in barr]
            if len([c for c in y if c in legal_chars]) > 0.99 * len(barr):
                ans.append((chr(i), len([c  for c in y if c == 'e'])))
        mx = max([a[1] for a in ans])
        ans.sort(key=lambda x:-x[1])
        print(ans)
        return [ans[i][0] for i in range(len(ans)) if ans[i][1] == mx][0]
    
    
    
    
    for keysz in range(29, 30):
        keyarr = []
        print('keysz', keysz)
        for keyi in range(keysz):
            subxt = [bx[i] for i in range(keyi, len(bx), keysz)]
            keyarr.append(try_solve(subxt))
        print(''.join(keyarr))
        
        
    

     

    感想:

    keysz=29,这个实际上是硬暴力来的

    其实还不完全,直接按照E的数目最多来拼是Terminator X: Br,ng thm noise

    但实际上应该是Bring the noise

  • 相关阅读:
    [RxSwift]3.3、数据绑定(订阅)
    [RxSwift]3.2、函数式编程 -> 函数响应式编程
    [RxSwift]2、Hello RxSwift!:我的第一个 RxSwift 应用程序
    [RxSwift]1、为什么要使用 RxSwift ?
    [RxSwift]RxSwift: ReactiveX for Swift
    [Swift]UIViewController
    104. 二叉树的最大深度
    103. 二叉树的锯齿形层次遍历
    102. 二叉树的层序遍历
    98. 验证二叉搜索树
  • 原文地址:https://www.cnblogs.com/xuesu/p/12000373.html
Copyright © 2011-2022 走看看