Python实现各进制转换的完整指南与CTF实战
本文总结Python中字符串与十六进制、二进制、八进制之间的转换方法,涵盖decode('hex')、hex()、binascii库及int()函数的使用。结合CTF赛题实例,提供二进制、ASCII、十六进制转字符串的Python脚本工具,帮助安全研究人员高效处理编码转换任务。
前言
前言
在参与CTF(Capture The Flag)网络安全竞赛时,进制转换是常见的考点。为了系统地梳理相关知识并分享给读者,本文将对各类进制转换方法进行详细总结与分享。
字符串与十六进制转换
字符串与十六进制转换
以百度CTF 12月第二场Misc类别的第一题为例进行说明。
666C61677B65633862326565302D336165392D346332312D613031322D3038616135666137626536377D
一种简便的处理方式是直接调用字符串的.decode('hex')方法进行解密。但如果不使用该内置方法,应当如何手动实现转换呢?
一种可行的思路是将字符串按每2个字符分组,分别计算每组对应的ASCII值,最后合并字符串即可得到结果。具体实现代码如下:
import re
s='666C61677B65633862326565302D336165392D346332312D613031322D3038616135666137626536377D'
s = re.findall(r'.{2}',s)
s = map(lambda x:chr(int(x,16)),s)
print ''.join(s)
>>>
flag{ec8b2ee0-3ae9-4c21-a012-08aa5fa7be67}
前文提到了字符串的decode('hex')方法,此外还有两个用于转换16进制的函数,这里一并总结。
内置函数hex()
该函数仅能将10进制整数转换为十六进制字符串,无法直接处理字符串类型的数据。
binascii库的hexlify()和b2a_hex()
这两个函数的作用是将字符串转换为十六进制表示,其对应的解密函数分别为unhexlify()和a2b_hex()。
进制互转
进制互转
将二进制、八进制、十六进制转换为10进制相对简单,直接调用相应函数即可。
int函数
int(str,base) //返回十进制整数,但注意此时第一个参数为字符串
其对应的解密(转换回其他进制)函数分别是:
bin() //10进制转二进制
oct() //十进制转八进制
hex() //十进制转十六进制
然而,若需将二进制直接转换为16进制,则需多一步操作:先使用int转换为十进制,再利用上述提到的hex()函数将十进制转换为十六进制。较为精简的写法如下:
map(lambda x:hex(int(x,2)),['0011']) //lambda表达式
或者采用列表解析的方式:
[hex(int(x,2)) for x in ['0011']] //列表解析
对应的解密函数即为:
map(lambda x:bin(int(x,16)),['ef'])
Python进制转换工具
最后附上一个使用Python编写的进制转换小工具,主要功能是将一组二进制、ASCII或十六进制数据转换为字符串。这类题型在CTF比赛中较为常见。
# make by 江sir
#coding:utf-8
import re
import argparse
def bintostr(text):
text = text.replace(' ','')
text = re.findall(r'.{8}',text)
s = map(lambda x:chr(int(x,2)),text) #批量二进制转十进制
flag = ''.join(s)
return flag
def asciitostr(text):
if ' ' in text:
text = text.split(' ')
elif ',' in text:
text = text.split(',')
s = map(lambda x:chr(int(x)),text)
flag = ''.join(s)
return flag
def hextostr(text):
text = re.findall(r'.{2}',text)
#print text
s = map(lambda x:chr(int(x,16)),text)
#print s
flag = ''.join(s)
return flag
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-b")
parser.add_argument("-a")
parser.add_argument("-x")
argv = parser.parse_args()
#print argv
if argv.b:
res = bintostr(argv.b)
elif argv.a:
res = asciitostr(argv.a)
elif argv.x:
res = hextostr(argv.x)
print res
用法说明:
十六进制转字符串示例:
666C61677B65633862326565302D336165392D346332312D613031322D3038616135666137626536377D
bintostr.py -x "666C61677B65633862326565302D336165392D346332312D613031322D3038616135666137626536377D"
flag{ec8b2ee0-3ae9-4c21-a012-08aa5fa7be67}
二进制转字符串示例:
输入数据可以包含空格,也可以不包含空格。
00101111 01100110 00110110 00110111 00110011 00110010 00110100 00110001 00110000 01100001 01100001 01100100 01100011 00110000 00110011 00110111 01100110 01100010 00110000 01100011 01100010 01100001 01100001 00110000 00110000 01100011 00110111 00110101 00110011 00110001 00110011 00110111 00110011 00101110 01110100 01111000 01110100
bintostr.py -b "00101111 01100110 00110110 00110111 00110011 00110010 00110100 00110001 00110000 01100001 01100001 01100100 01100011 00110000 00110011 00110111 01100110 01100010 00110000 01100011 01100010 01100001 01100001 00110000 00110000 01100011 00110111 00110101 00110011 00110001 00110011 00110111 00110011 00101110 01110100 01111000 01110100"
/f6732410aadc037fb0cbaa00c7531373.txt
ASCII转字符串示例
分隔符可以是空格,也可以是逗号。
s='45 46 45 46 32 45 32 46 46 45 46 32 46 45 46 46 32 46 46 46 32 45 46 46 46 32 46 46 45 45 46 45 32 45 46 46 46 32 46 46 46 32 46 45 46 46 32'
bintostr.py -a "45 46 45 46 32 45 32 46 46 45 46 32 46 45 46 46 32 46 46 46 32 45 46 46 46 32 46 46 45 45 46 45 32 45 46 46 46 32 46 46 46 32 46 45 46 46 32"
-.-. - ..-. .-.. ... -... ..--.- -... ... .-..
以上实例均来源于部分CTF赛题。
总结
总结
以上就是本文的全部内容,希望这些内容能对各位的学习或工作有所帮助。如有任何疑问,欢迎留言交流,感谢大家对本站的支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













