- 这是一道看起来很美的题。有关uuencode编码的,要事先了解一下uuencode的编码原理。
- 本来想自己写出解码的脚本的,但是,作业有多,事儿又多,其实主要还是自己菜。于是就重新抄了一篇官方解答的脚本代码,写上自己的理解吧!就当做是复习python吧。
#!/usr/bin/env python3
# This script helps you decode "her poem"
def is_line_contain_flag(line):
left = line[0]-32 #uuencode的编码格式第一个是这一行的字节个数,由此算出原来的字节个数,以判断是否隐藏了flag
return left*4%3 #返回的其实是uuencode编码后剩余的字节个数
def get_hidden_bits(line):
left = is_line_contain_flag(line)
assert(left != 0)
if left == 1:
return (line[-3]-32) & 0b1111
else:
return (((line[-2]-32) & 0b11)<<2) | (((line[-1]-32) & 0b1100)>>2)#提取隐藏的flag bits
if __name__ == '__main__':
fin = open("poem.txt", "r")
fout = open("flag.txt", "w")
enc_lines = fin.read().splitlines()
enc_lines = list(map(lambda x:bytes(x,encoding='ascii'),enc_lines))#map函数的作用很好用,lambda表达式我也重新复习了一下,总感觉不编程,就会忘了python
lines_contain_flag = []
flag = ''
for i in enc_lines:
if is_line_contain_flag(i):
lines_contain_flag.append(i)
else:
continue
assert(len(lines_contain_flag) % 2 == 0)
for i in range(len(lines_contain_flag)):
if i % 2 == 0:#????
print(i)
print(bin(get_hidden_bits(lines_contain_flag[i])<<4))
print(bin(get_hidden_bits(lines_contain_flag[i+1])))
flag_chr = (get_hidden_bits(lines_contain_flag[i])<<4) | (get_hidden_bits(lines_contain_flag[i+1]))
print(flag_chr)
assert(flag_chr <= 0b01111111)#断言字符在ASCII中,验证的时候也体会到了assert的作用,在调试时可以迅速判断错误的出处
flag += chr(flag_chr)
print(flag)
fout.write(flag)
fin.close()
fout.close()