python3解密栅栏密码的正确方法
今天在做ctf时想找一个栅栏密码的解密脚本,在网上搜过了下,发现竟然没找到一个正确的脚本(也可能是自己的搜索水平太差),倒不是说大家的脚本都有问题,只是在解决特殊情况时会出错。
比如这个帖子里的:
https://blog.csdn.net/weixin_42109012/article/details/97535995
如果加密abcdef 每组字数为4,那么加密后应该是aebfcd,但是按上面的那个贴子里的代码去解密会得到acedbf
再比如这个里面的:
https://blog.csdn.net/abc_12366/article/details/87197344
这个代码也算不出我给的情况,并且里面用的参数是分多少栏,这个我觉得也是不合适的,因为假如字符串有长度为7,分为2栏的话,就会几种情况:
- 每组字数为4,那么第一组为4,第二组为3
- 每组字数为5,那么第一组为5,第二组为2
- ……
而这几种情况加密后的结果是不一样的,所以必须规定每组字数,才更为准确。
为了解决这种不字符长度不能被每组字符数整除的情况,我考虑了好一会,开始想人为的分组,或者分不同余数情况来分别处理,最后效果都不好。
最终我想出来一个比较合适的算法就是补位。
例如上面的例子:aebfcd, 每组字符数为4
字符串长度为6,不能被4整除,那么就补位,因为4*2=8, 那么需要补2位
如果用-代替补位,那么就是aebfc-d-,再进行解码就很好解了,用前面两个文章里的代码都能解出来。其实程序不难,关键是想到怎么样才能解决不能整除的特殊情况。
完整的代码如下:
# _*_ encoding:utf-8 _*_
import mathdef buwei(encrypted_str,fence_length): # 比如 14,4str_len = len(encrypted_str)fence_count = math.ceil(str_len/ fence_length) # 得出4target_length = fence_count*fence_lengthjiequ = []while str_len<target_length:encrypted_str = encrypted_str + '*'jiequ.append(encrypted_str[-fence_count :])encrypted_str = encrypted_str[:-fence_count]str_len += 1jiequ.reverse()s = ''for i in jiequ:s = s + iresult = encrypted_str + sreturn resultdef decrypt_fence(encrypted_str,fence_length):encrypted_str = buwei(encrypted_str,fence_length)if fence_length>=len(encrypted_str) or fence_length<1:print("栅栏长度太大或者太小,无需解密")returnfence_count = math.ceil(len(encrypted_str)/fence_length)elen=len(encrypted_str)# b = elen // f # 用字符串实际长度除以上面计算出能整出的数字fresult = {x: '' for x in range(fence_count)}for i in range(elen): # 字符串有多少位,就循环多少次a = i % fence_countresult.update({a: result[a] + encrypted_str[i]}) # 字符串截断,并更新数据d = ''for i in range(len(result)):d += result[i]d = d.replace("*", '')print(f'假设每栏字数为:{fence_length},解密结果为:{d}') # 输出结果,并开始下一个循环decrypt_fence('adbecf', 4)
经测试,可以正确的处理各种不被整除的情况,本人业余编程爱好者,如果有代码有错误或者要改进的地方,欢迎大家评论,另外如果有更好的算法,也请告知我下,谢谢啦。