type
status
date
slug
summary
tags
category
icon
password
书接上回,自从了解了cython,就很想实际操作一回,结果刚好做到个题可以爆破,就直接试一试了。
题目:
题目的cipherText是autokey加密,预期解的话直接拿https://github.com/im5h/breakautokey_py3/ 就打掉了。不必多说。
但我发现这里的autokey原始密钥仅7字节(并且都是大写字母),其实是可以考虑直接爆破的,后面的sm4_cbc需要autokey的原始密钥和plaintext的前十六个字节。如果知道原始密钥key的话,利用模运算就可以恢复前十六个字节的明文。所以遍历找7个字节的全排列就行了。因此这就有了我的狗屎Cython代码。我把通过key推明文的部分用c语言实现:
然后写了cython代码get_text.pyx直接extern from function.c
然后弄一个打包的代码:
执行打包代码就能生成get_text.pyd了。
弄一个爆破脚本,直接调get_text
测了一下上边的爆破范围大概要60秒才能跑出结果。这实在太慢了,和纯Python的差不多。于是我又想着把GIL锁去掉然后用多线程。主要是修改pyx部分,改成了下面这样:
在
with nogil
内部的代码完全不能出现python对象(包括参数),否则会报错。然后解密代码变成了:
ok一测试把我都吓到了,跑的巨慢无比。其实原因很简单,这里对autokey的破解并不是非常耗费资源的运算,因为它只是简单的模运算。但是一直在进行上下文的切换(不断调用),消耗资源巨大。再仔细一看,这里并行了个毛,每次传入的k都不一样,并行应该是多个核心并发跑一样的东西。这里单传入一个很小的参数一下就执行完了根本没用到多核。
因此要实现高效多核并发的条件是:1.运算的cpu开销密集(比如这里的sm4解密)2.对开销密集的代码作为多线程(进程)执行的函数 3.尽量减少上下文开销,一次传入一批参数而非单一参数(batch_size)。到这里也不想再去实现get_text_func的batch版本了,用python多进程试了试,跑出结果只要3.5s。不得不说写代码之前还是应该先想好再动手,对并发的理解还是不深。
- Author:ZimaBlue
- URL:https://www.zimablue.life/article/cython1
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!