解决python3 整数数组转bytes的效率问题

作者:b0ring 时间:2023-08-09 19:39:41 

昨天在做一道CTF题的时候碰到了一个图片异或的问题,操作大概如下:

将一个图片读入,然后每字节进行异或操作,核心代码可简化为以下:


#coding:utf-8
'''
@DateTime: 2017-11-25 13:51:33
@Version: 1.0
@Author: Unname_Bao
'''
import six
key = b'\xdcd~\xb6^g\x11\xe1U7R\x18!+9d\xdcd~\xb6^g\x11\xe1U7R\x18!+9d'
with open('flag.encrypted','rb') as f:
c = f.read()
flag = b''
for i in range(32):
flag += six.int2byte(key[i%32]^c[i])
with open('flag.png','wb') as f:
f.write(flag)

然后就碰到了一个效率问题,跑了十几分钟都没有跑出结果,起初以为是类型转换的问题,因为比较急,于是换了成了C++的代码去解决,后来一直没多想。

今天闲下来的时候才发现代码之前的代码中存在一个非常大的问题:

内存申请问题

由于flag.encrypted文件大小为6.47MB之大,由于我的脚本思路是不断在byte数组后添加,但忽略了其本质。

就是在内存申请过程中,由于数组长度最终为600+W大小,期间存在多次数组内存不够,需要重新申请内存的问题,而python中的内存申请显然没有C++的vector的push_back有效率。

而且python中,无论是list、string还是byte,也没有reserve这种函数,不能预留内存空间(这时候真的要吐槽一下python设计者对速度优化的考量了)。

于是只能用另一种方法进行优化,就是先用list申请一个需求大小的内存空间,然后再转为bytes使用,

代码如下:


#coding:utf-8
'''
@DateTime: 2017-11-26 14:09:29
@Version: 2.0
@Author: Unname_Bao
'''
key = b'\xdcd~\xb6^g\x11\xe1U7R\x18!+9d\xdcd~\xb6^g\x11\xe1U7R\x18!+9d'
with open('flag.encrypted','rb') as f:
c = f.read()
flag = list('1'*len(c))
for i in range(len(c)):
flag[i] = key[i%32]^c[i]
flag = bytes(flag)
with open('flag.png','wb') as f:
f.write(flag)

这样写的话几乎是瞬间完成任务了,但还是比C++慢很多,这是不可避免的。

补充:python2与python3的bytes问题


>>> s = '编程'
>>> print s
编程
>>> s
'\xe7\xbc\x96\xe7\xa8\x8b'
>>>

在python2中直接调用字符串的变量的话,会打印其bytes(可以理解成用16进制表示字符串的内存地址,本质还是二进制)。在python2中,bytes和str是一回事。

为什么要有个bytes呢?因为所有数据本质都是用二进制进行储存的,当传输数据的时候,要把这些数据先转换成二进制( bytes)在进行传输。除此之外,python2里还有个单独的数据类型,把字符串解码后,就会变成unicode。


>>> s
'\xe8\xb7\xaf\xe9\xa3\x9e' #utf-8
>>> s.decode('utf-8')
u'\u8def\u98de' #unicode 在unicode编码表里对应的位置
>>> print(s.decode('utf-8'))
路飞 #unicode 格式的字符

原因是python2的默认编码是ASCII,后来为了支持多国语言,就想弄个unicode。但是直接把ASCII转成unicode是很费劲的,所以龟叔直接搞了一个新的字符类型,就叫unicode,说白了就是你得在内存里先把字符串存成unicode类型

2008年python3出世,来了个大变革:

1、把字符串的编码变成了unicode,文件默认编码变成了utf-8。

2、把str 和bytes 做了明确区分, str 就是unicode格式的字符, bytes就是单纯二进制还有一个很重要的是,在python3中,只有unicode给你展示字形,其他的编码一律用bytes展示,也就是说要你强制使用unicode。

最后再提示一下,Python只要出现各种编码问题,无非是哪里的编码设置出错了

常见编码错误的原因有:

Python解释器的默认编码

Python源文件文件编码

Terminal使用的编码

操作系统的语言设置

以上为个人经验,希望能给大家一个参考,也希望大家多多支持

来源:https://blog.csdn.net/s1054436218/article/details/78637048

标签:python3,整数,数组,bytes
0
投稿

猜你喜欢

  • python matplotlib库直方图绘制详解

    2023-01-19 06:38:34
  • 一篇文章带你搞懂Go语言标准库Time

    2024-05-09 09:54:35
  • 上传组件 ASPUpload 使用说明

    2008-09-11 14:38:00
  • python广度搜索解决八数码难题

    2023-01-26 18:12:43
  • 友情连接地址代码-线线表格

    2010-07-01 16:26:00
  • java URL 获取PHP JSON 数据

    2023-11-14 18:02:02
  • python虚拟环境完美部署教程

    2021-09-10 17:54:02
  • Xml中SelectSingleNode方法中的xpath用法

    2010-01-30 12:46:00
  • CodeIgniter启用缓存和清除缓存的方法

    2023-11-22 17:04:55
  • python 多线程实现检测服务器在线情况

    2021-12-11 15:15:58
  • python中getaddrinfo()基本用法实例分析

    2023-03-15 12:17:34
  • python持久化存储文件操作方法

    2022-06-10 00:59:34
  • 深入探讨:PHP使用数据库永久连接方式操作MySQL的是与非

    2023-11-20 22:41:16
  • python利用多种方式来统计词频(单词个数)

    2021-12-23 14:52:32
  • Python redis模块的使用教程指南

    2021-03-22 12:08:02
  • Python Asyncio 库之同步原语常用函数详解

    2021-04-27 03:50:39
  • python获取本机所有IP地址的方法

    2022-08-01 16:38:55
  • golang语言map全方位介绍

    2024-05-22 10:20:33
  • SQL Server如何保证可空字段中非空值唯一

    2024-01-17 07:19:03
  • 好用的asp防SQL注入代码

    2008-10-24 08:36:00
  • asp之家 网络编程 m.aspxhome.com