继续挑战
第21题为第20题对unreal.jpg用特定的Range
请求得到的压缩包内容
- 压缩包里面有一个
package.pack
文件,题目readme.txt
内容为:- We used to play this game when we were kids
- When I had no idea what to do, I looked backwards.
先重复上一题的步骤把package.pack
解压出来看看:
from io import BytesIO
from zipfile import ZipFile
import requests
with requests.Session() as sess:
sess.auth = ('butter', 'fly')
header = {'Range': 'bytes=1152983631-'}
response = sess.get('http://www.pythonchallenge.com/pc/hex/unreal.jpg', headers=header)
with ZipFile(BytesIO(response.content), 'r') as f:
with f.open('package.pack', 'r', pwd=b'invader'[::-1]) as f_pack:
package = f_pack.read()
print(package[:20])
b'x\x9c\x00\n@\xf5\xbfx\x9c\x00\x07@\xf8\xbfx\x9c\x00\x06@\xf9'
查了下b'x\x9c\x00
开头的是zlib
压缩格式,我们来解包看看:
import zlib
temp = zlib.decompress(package)
print(temp[:20])
b'x\x9c\x00\x07@\xf8\xbfx\x9c\x00\x06@\xf9\xbfx\x9c\x00\xff?\x00'
又玩这种循环迭代的游戏了!那我们继续:
import zlib
data = package
while True:
try:
data = zlib.decompress(data)
except Exception as e:
print(data[:20])
print(f'{e!r}')
break
b'BZh91AY&SY\x91\xe8/+\x00v\xa9\x7f\xff\xff'
error('Error -3 while decompressing data: incorrect header check')
咦?切换到了BZh
开头的bzip2
压缩格式了,我们改一下继续:
import bz2
import zlib
data = package
while True:
try:
data = zlib.decompress(data)
except:
try:
data = bz2.decompress(data)
except Exception as e:
print(data[:20])
print(f'{e!r}')
break
b'\x80\x8d\x96\xcb\xb5r\xa7\x00\x06Xz\xdafO\x19\xee\x84k\xa4d'
OSError('Invalid data stream')
这回不知道是什么东西了。。。来,我们开始读题。
说这是我们小时候会玩的游戏,我们刚才是在反复解压同一个东西,估计这个游戏就像是一个东西在小伙伴里面不断地传递,每个人会给它用某种方式(压缩)包装一层再继续。我们在做的事情就是解压拿到最原始的内容。没毛病,但是现在我们卡壳了。
再看看第二句话,当我们卡壳的时候,会试着倒过来看:
print(data[::-1][:20])
b'x\x9c\x00\x0c@\xf3\xbfx\x9c\x00\x05@\xfa\xbfx\x9c\x00\x05@\xfa'
果然有用!!
我们改一下继续:
import bz2
import zlib
data = package
try_count = 0
while True:
try:
data = zlib.decompress(data)
except:
try:
data = bz2.decompress(data)
except:
data = data[::-1]
try_count += 1
if try_count == 3:
print(data[:20])
break
continue
try_count = 0
print(data.decode())
b'look at your logs'
look at your logs
解压出来最原好的内容了!但是叫我们看日志,看来要加上一些打印来记录我们的解压操作了。
在我们继续之前,首先是我发现了一个叫python-magic
的库,可以知道文件内容的具体格式,不用我们总是去查找。至少可以优化一下上面那段那么丑的代码吧。
from magic import Magic
magic_t = Magic(mime=True)
print(magic_t.from_buffer(package))
application/zlib
其次是我们有三种不同的操作,需要定义其打印的字符:
操作 | 打印字符 |
---|---|
zlib | ’.’ |
bz2 | ‘0’ |
倒序 | ‘\n’ |
import bz2
import zlib
from magic import Magic
magic_t = Magic(mime=True)
data = package
while True:
mime = magic_t.from_buffer(data)
if mime in ('application/zlib', 'application/x-tex-tfm'):
data = zlib.decompress(data)
print('.', end='')
elif mime == 'application/x-bzip2':
data = bz2.decompress(data)
print('0', end='')
else:
data = data[::-1]
print()
if mime == 'text/plain':
break
print(data.decode())
......000..........000......00000000....00000000....0000000000..00000000
....0000000......0000000....000000000...000000000...000000000...000000000
...00.....00....00.....00...00......00..00......00..00..........00......00
..00...........00.......00..00......00..00......00..00..........00......00
..00...........00.......00..000000000...000000000...00000000....000000000
..00...........00.......00..00000000....00000000....00000000....00000000.
..00...........00.......00..00..........00..........00..........00...00.
...00.....00....00.....00...00..........00..........00..........00....00.
....0000000......0000000....00..........00..........000000000...00.....00.
......000..........000......00..........00..........0000000000..00......00
look at your logs
好大一个COPPER
!将地址改为copper.html,来到了下一题。