梳理python语言中的字符串编码与解码问题,包括字符串与其二进制、十六进制的转化方法。
0x00 概述
使用过多版本python(2. / 3.)的朋友一定会遇到关于字符串编码类型的问题。这是因为python3中新引入了一种数据类型bytes
。bytes
类型的含义是字节字符串,也就是以字节形式(8 bits
)存储的字符串,通常以16进制显示。str
类型需要通过编码变成bytes
类型,bytes
类型需要通过解码变成str
。而具体的编码形式,取决于字符串想采用哪种编码方法,例如UTF-8
、GBK
、ASCII
。python3中的默认编码格式是UTF-8
。
下面这个图表示了这种转换关系
1 | # string encode to bytes |
From https://blingblingxuanxuan.github.io/2021/01/23/study-python3/
0x01 字符串二进制表示转换
二进制字符串转ASCII
1 | # 字符串长度应该是8的倍数 256个ASCII字符 把字符串按照8位的长度切割 |
二进制字符串转化为bytes
1 | bin_str = '1011001110110111' |
0x02 十六进制表示转换
在CTF比赛中,我们经常需要将字符串转化为16进制表示或者将16进制表示转化为字符串。
下面介绍几种常用的方法:
方式一:通过bytes.hex()
函数和bytes.fromhex()
函数
1 | 'os').popen('cat flag.txt').read() # str __import__( |
方式二:借助binascii
库中提供的转换函数b2a_hex
、a2b_hex
1 | import binascii |
0x03 进制转换
在CTF中有些场景,我们需要实现字符串和整数之间的转换
1 | # 首先我们可以借助int()函数实现进制转换 |
0x04 Bytes<–>Integer
方式一:借助bytes_to_long
和long_to_bytes
函数
1 | # bytes_to_long |
方式二:进制转换
1 | 'THUCTF{123jkljljfkj322k3jJLIJIHih}\n'.encode().hex() , 16) int( |
方式三:借助Integer
类型的库函数to_bytes
和from_bytes
https://docs.python.org/3/library/stdtypes.html?highlight=to_bytes#int.to_bytes
to_bytes
函数第一个参数是想转换成的字节长度,如果太小会出现overflow。第二个参数是字节序,可以填写大端或者小端。
from_bytes
可以直接将bytes
转换为整数,和bytes_to_long
的功能基本一致。目前暂不确定两者的区别。
1 | b'THUCTF{123jkljljfkj322k3jJLIJIHih}\n', 'big') int.from_bytes( |
0x00 输出格式
1 | # 把bytes打印成0x格式 |