StevenPZChan
StevenPZChan
3 min read

Categories

Tags

继续挑战,来到了新的区域


第19题地址bin.html

  • map.jpg
  • 网页标题是please!,题目内容为空,源码里面隐藏着好大一段内容:

    <!–
    From: leopold.moz@pythonchallenge.com
    Subject: what do you mean by “open the attachment?”
    Mime-version: 1.0
    Content-type: Multipart/mixed; boundary=”===============1295515792==”

    It is so much easier for you, youngsters.
    Maybe my computer is out of order.
    I have a real work to do and I must know what’s inside!

    –===============1295515792==
    Content-type: audio/x-wav; name=”indian.wav”
    Content-transfer-encoding: base64

    UklGRvyzAQBXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YdizAQBABkAMQAtAAEADQAJA

    PwRACEAGPwpADj8JQBA=

    –===============1295515792==–

    –>

图片是一张印度India地图,隐藏信息看上去是一封邮件,说是电脑混乱了打不开附件云云。
附件是一个文件名为indian.wav的音频文件,用base64编码并用明文显示了出来。
先把音频搞下来听听:

import email.policy
import re
import requests
from IPython.display import Audio

with requests.Session() as sess:
    sess.auth = ('butter', 'fly')
    response = sess.get('http://www.pythonchallenge.com/pc/hex/bin.html').text
    email_str = re.findall(r'<!--(.*?)-->', response, re.DOTALL)[0]
    
leopold_email = email.message_from_string(email_str.strip(), policy=email.policy.HTTP)
for part in leopold_email.walk():
    if part.is_multipart():
        continue
    elif part.get_content_maintype() == 'audio':
        indian = part.get_content()

Audio(indian, autoplay=True)
                
              

Sorry??

我们把地址改为sorry.html,提示:

  • “what are you apologizing for?”

还是没什么头绪啊,看来问题并不简单。不过存在这个页面说明音频文件没问题,可能是要做一些音频处理了。

首先图片是一张印度India地图,而音频文件名叫indian.wav,会不会暗示着什么?
再结合看邮件内容,说是电脑out of order混乱了,emmm,此indian该不会是指彼endian吧?!

字节顺序,又称端序或尾序(英语:Endianness),在计算机科学领域中,指存储器中或在数字通信链路中,组成多字节的字的字节的排列顺序。
在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x100,那么其对应地址表达式&x的值为0x100。且x的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置。
字节的排列方式有两个通用规则。例如,一个多位的整数,按照存储地址从低到高排序的字节中,如果该整数的最低有效字节(类似于最低有效位)在最高有效字节的前面,则称小端序;反之则称大端序。在网络应用中,字节序是一个必须被考虑的因素,因为不同机器类型可能采用不同标准的字节序,所以均按照网络标准转化。
例如假设上述变量x类型为int,位于地址0x100处,它的值为0x01234567,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:0x100: 01, 0x101: 23,..。而小端法将是:0x100: 67, 0x101: 45,..。

From wikipedia.org

在网络传输中默认会使用大端序,我们来改成小端序:

import sys
import wave
from io import BytesIO

with wave.open(BytesIO(indian)) as big, BytesIO() as f, wave.open(f, 'w') as little:
    little.setparams(big.getparams())
    frames = big.readframes(big.getnframes())
    sys.byteorder = 'big'
    little.writeframes(frames)
    endian = f.getvalue()
    sys.byteorder = 'little'
    
Audio(endian, autoplay=True)
                
              

You are an idiot! Hahaha…

什么鬼?还带骂人的。。。
我们把地址改成idiot.html

  • leopold.jpg
  • 网页标题是-idiot ?,内容为"Now you should apologize..."并且给出了下一题的链接!idiot2.html

整理一下,是说我们给Leopold发了封带附件音频indian.wav的邮件,结果对方电脑字节序不对打不开。
然后我们按错误的字节序打开后发现说的是sorryLeopold就问你道歉个啥。
然后我们再按正确的字节序打开后发现是骂idiot的,难怪Leopold知道了会说你应该道歉云云。。。

总结:这一题要用到一些内存的知识,知道了字节序的内容。学习了emailwave库的使用,和jupyter使用IPython.display.Audio来播放音频的相关操作。

本题代码地址19_bin.ipynb