PythonChallenge_3

一、实验说明

1. 环境登录

无需密码自动登录,系统用户名shiyanlou,密码shiyanlou

2. 环境介绍

本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面上的程序:

1. LX终端(LXTerminal): Linux命令行终端,打开后会进入Bash环境,可以使用Linux命令
2. Firefox:浏览器,可以用在需要前端界面的课程里,只需要打开环境里写的HTML/JS页面即可
3. GVim:非常好用的编辑器,最简单的用法可以参考课程[Vim编辑器]

3. 环境使用

使用GVim编辑器输入实验所需的代码及文件,使用LX终端(LXTerminal)运行所需命令进行操作。

完成实验后可以点击桌面上方的“实验截图”保存并分享实验结果到微博,向好友展示自己的学习进度。实验楼提供后台系统截图,可以真实有效证明您已经完成了实验。

实验记录页面可以在“我的主页”中查看,其中含有每次实验的截图及笔记,以及每次实验的有效学习时间(指的是在实验桌面内操作的时间,如果没有操作,系统会记录为发呆时间)。这些都是您学习的真实性证明。

二、课程介绍

本次`PythonChallenge`系列一共有11个项目,持续更新中~~~,每个项目课程里面会详细讲解3个`pythonchallenge`通关题目以及不同解决方案,课后习题里面布置一个任务题,该题目会在下一个项目中被揭开面纱。

本系列题目属于在线闯关题,由于实验楼暂时不提供访问外网,因此请各位验证答案的时候烦劳点击自己的浏览器访问网页以验证答案。

所有题目和参考的解决方案版权归[PythonChallenge官网],课程编写属于实验楼原创,欢迎在问答区积极提问,小编会积极解答,也欢迎在评论区吐槽~

三、实验回顾

在上一个[项目课]中,我们学到了很多知识,比如:`re`模块中的一些函数,`urllib`模块的使用以及函数`reduce`。记性不算太差的你们估计还记得在上一次的课程中小编有留给大家一个课后作业,不知道你们完成的怎样呢?

不管是否得到答案,让小编带着你一起解决这个问题吧!

四、作业题解析

### 问题:请访问[挑战题链接]查看源代码,找到通往下一个网址的链接。(提示:与`zip`有关)

**小编脑洞:**

首先查看源代码:

经过这几次题目的摸索,我们知道一般答案都是隐藏在注释里面的(`<!-- -->`的内容)。首先第一个注释是单词`zip`,第二个注释稍微比较长,大致的意思是:下面的内容与谜语本身无关,只希望大家能够给`pythonchallenge`这个项目提供一点资助。那么,第二个注释就没有什么作用。再看第一个注释,只有一个单词`zip`,那么答案就是`zip`了,因此修改链接为:[http://www.pythonchallenge.com/pc/def/zip.html]。得到这样的结果:

意思是:找到了`zip`,那么`zip`应该就隐藏在源代码中:

源码中并没有给予什么信息,那么是不是`zip`指的是`zip`压缩包呢?再次返回修改原链接,将`html`换成`zip`,结果真是一个压缩包,关于这个压缩包,已经上传至实验楼环境,因此输入以下命令下载文件并查看压缩包内容:

 $ wget http://labfile.oss.aliyuncs.com/courses/411/channel.zip
$ unzip -l channel.zip

文件内容如下:

一共有910个文件,大多数文件的命名都是数字型,解压并查看说明文档`readme.txt`:

 $ unzip channel.zip
$ vi readme.txt

根据上面的提示,我们了解到两个信息:

  1. 循环是从`90052.txt`这个文件开始;
  2. 答案就隐藏在zip压缩包文件夹的内容中。

查看`90052.txt`这个文档内容如下:

看到这句话的时候,你是不是觉得似曾相识?是的,在上一个挑战项目中也出现过这么一句话,区别在于上一次的题目是使用`urllib`模块在网页上寻找关键字,这一次是在压缩包内寻找答案。

算法如下:

  • 1. 设置初识起点,进入循环,使用正则表达式匹配文件内容中的数字;
  • 2. 将文件内容中的数字作为下一个被打开的文件名;
  • 3. 循环条件是找到不是以数字结尾的文件并打印结果
 import re

 findnothing = re.compile(r'Next nothing is (\d+)').match

 while True:
fname = seed + 'txt'
text = open(fname, 'r').read()
m = findnothing(text)
if m:
seed = m.group(1)
else:
print text
break

打印结果如下:

意思是让我们收集注释。

关于注释,每一个文件都有它的描述信息,可以通过输入命令查看压缩包内的文件的描述信息:

 unzip -l channel.zip

上图给出每个文件的四个信息,比如`reame.txt`文件,它的注释信息就是`*`,该文件的大小为`84`字节,该文件的最后修改时间是`2005-04-28`,文件名为`readme.txt`。将这些注释信息连接起来就可以看看结果能不能告诉我们信息。

`Python`中有一个关于收集压缩包信息的模块`zipfile`,该模块的详细说明文档见[官方文档](https://docs.python.org/2/library/zipfile.html)。
该模块中有一个类需要我们了解——`zipfile.ZipFile`。该模块主要用于读写`zip`类型的文件。该类里面有一个函数`getinfo(name)`用于返回压缩文件中命名为`name`的文件信息,由于本次示例里面需要用到文件信息里面的解释部分,因此直接调用`zipfile.ZipFile.getinfo(name).comment`就可以返回`name`文件的注释。

因此修改代码如下:

 import zipfile, re

 findnothing = re.compile(r"Next nothing is (\d+)").match
comments = [] # 收集注释信息的列表
z = zipfile.ZipFile("channel.zip", "r") # 读取压缩包文件
seed = "" while True:
fname = seed + ".txt"
comments.append(z.getinfo(fname).comment)
guts = z.read(fname)
m = findnothing(guts)
if m:
seed = m.group(1)
else:
break
print "".join(comments) # 打印所有注释信息

那么答案应该就是`hockey`了,转到该链接:

然后提示让我们看一下字母,并且提示该单词指的是存在于空气中。上面组成`HOCKEY`的图中恰好是由字母`O C Y G E N`组成,也就是单词空气——`oxygen`。

因此来到[下一题]

五、第七个挑战题

问题:根据这副图片找到通往下一个链接的单词。

**小编脑洞:**

然而这一次源代码中并没有提供额外的信息,那么只能看图,仔细观察上图,发现这个图并不完整,图的中间被一条不同深度的灰度长条给掩盖,那么信息很可能就隐藏在这里面。那么图像处理中我们知道每一个图片都是由无数个像素值组成,实际上就是一个[像素]构成的矩阵,那么答案很可能与这些像素值有关。关于这个问题的具体思路,有兴趣的朋友可以看一下我的[博客]

首先下载用于处理图像的`Image`模块,然后下载本题所需要处理到的图片`oxygen.png`。

 $ sudo apt-get install python-imaging
$ wget http://labfile.oss.aliyuncs.com/courses/411/oxygen.png

输入以下代码观察图片的大小:

 import Image
img = Image.open('oxygen.png')
img.size

由`img.size`的返回结果可知,该图片的水平方向和垂直方向上每英寸长度上的像素分别为`629`和`95`;利用画图工具可将这段马赛克区域的坐标提取出来:

横坐标的范围是:`0-609`,纵坐标的范围是:`43-53`。

然后利用`Image`模块里面的函数`getpixel`获得这一区域的像素数据:

 # 列表表达式
data = [img.getpixel((i, j)) for i in range(0, 609) for j in range(43, 53)]
print data

观察打印的结果,你会发现输出的像素列表是一个`4`元组,其中元组的前三个元素分别对应相应的`RGB`分量:`r`、`g`、`b`,并且由于灰色满足条件是`r=g=b`,且观察到元组每重复7次变化一次,那么如何将这些输出结果与答案联系?

一般情况下,答案的链接都是英文字母,那么可以尝试把这些数值转化为经过函数`chr`将这些`ASCII码`转换为相应的英文字母。

 # 先选取印第45行的所有像素信息
row = [chr(img.getpixel((i, 43))[0]) for i in range(0, 609, 7)]
"".join(row)

上图给的那句话的意思是下一关的答案是`[105,110,116,101,103,114,,105,116,121]`。好说,将这些`ASCII码`转为字母,并连接成字符串:

通往下一关的单词是`integrity`,因此转到下一关[链接]

七、第八个挑战题

问题:找到消失的链接

**小编脑洞:**

找到消失的链接?那么通关口应该不是简单的单词替换而是一个超链接,看看源代码是否有我们需要的信息:

我们注意到在`center/img`中有一个属性`usemap`为`notisect`,关于`notisect`的描述在`\map\area`下面有描述,也就是说这是`interity`这个图里面的链接,关于`coords`的内容是图片的某一区域,该区域指向一个链接`@href='../return/good/html'`点击图片弹出如下对话框(更多关于`img`标签的`usemap`属性介绍请查看[文档]):

也就是说我们需要在原网页中找到用户名和密码才能登陆该身份验证。

再次观察源代码中的注释部分,发现:

如果把`un`(username)后面的字符串解释为用户名,那么`pw`(password)里面的字符串就是密码。

那么这些字符串应该如何解码呢?仔细观察字符串的组成形式,无论是用户名还是密码都是`BZ`开头的字符串,后来了解到`BZ`开始的字符串实际上是被`bz2`压缩后的一种格式,那么如何解压呢?首先导入该模块,然后输入`dir(bz2)`查看`bz2`模块的函数:

`compress`是`压缩`函数,那么`decompress`就是解压函数,继续查看函数用法:

由于我们的字符串比较少,因此可以使用函数`decompress(data)`解压数据:

 import bz2
un = ''BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw = 'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'
bz2.decompress(un)
bz2.decompress(pw)

得到用户名为`huge`,密码为`file`,其实这个问题很简单,只要了解到`BZ`这种格式的字符串是一种压缩形式,然后进行相应的解压就可以解决问题。

八、任务

问题:请把点连接起来,[题目链接](提示:源代码,源代码!)。

pythonchallenge(三)的更多相关文章

  1. pythonchallenge 解谜 Level 3

    第三关. 问题的解法在于正则表达式. 首先...你应该能找到需要正则的字符在哪里...那就好了! 题意就是说: One small letter, surrounded by EXACTLY thre ...

  2. pythonchallenge(二)

    PythonChallenge_2 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux ...

  3. pythonchallenge(一)

    PythonChallenge_1 一.实验说明 下述介绍为实验楼默认环境,如果您使用的是定制环境,请修改成您自己的环境介绍. 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码sh ...

  4. Pythonchallenge一起来闯关

    http://www.pythonchallenge.com/是一个在线的python过关游戏,一共有33关.玩这个游戏对熟悉python用法及相关库的使用都很有好处. 目前做到了第九关.python ...

  5. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  6. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  7. Jquery的点击事件,三句代码完成全选事件

    先来看一下Js和Jquery的点击事件 举两个简单的例子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...

  8. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  9. 简谈百度坐标反转至WGS84的三种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 基于百度地图进行数据展示是目前项目中常见场景,但是因为百度地图 ...

随机推荐

  1. Solr5.0源码分析-SolrDispatchFilter

    年初,公司开发法律行业的搜索引擎.当时,我作为整个系统的核心成员,选择solr,并在solr根据我们的要求做了相应的二次开发.但是,对solr的还没有进行认真仔细的研究.最近,事情比较清闲,翻翻sol ...

  2. 用memoization优化递归算法[JS/PHP实现]

    递归函数,通过把一个大而复杂问题简化为许多但规模较小的问题,以同一个相似模式来计算,降低了解题的难度:通过调用自身函数,极大地减少了函数代码量的优点而为开发者喜爱.但因其不断调用自身函数开辟新栈,且大 ...

  3. Ubuntu15.04装机配置脚本

    #!/bin/bash echo "vim" sudo apt-get install vim cp -r ./vim/.vim ~/ cp ./vim/.vimrc ~/ ech ...

  4. 初次使用Docker的体验笔记

    一.前言 Docker容器已经发布许久,但作为一名程序员如今才开始接触,实在是罪过--        在此之前,我还没有对Docker进行过深入的了解,对它的认识仍停留在:这是一种新型的虚拟机.这样的 ...

  5. Openwrt LuCI模块练习详细步骤

    前言 又到了成胖子^_^每周一博的时间了.最近在学习openwrt luci方面的知识,为了贯穿整个知识体系,练习题目为: 通过页面配置周期性地往/tmp/addtest文件写入内容和时间戳 1.在w ...

  6. JS判断浏览器类型及版本

    浏览器 ie firefox opera safari chrome 分类: 一路辛酸---JavaScript 你知道世界上有多少种浏览器吗?除了我们熟知的IE, Firefox, Opera, S ...

  7. 基于元数据的ETL系统

     从努力到选择  从实现到设计 从部分到整体 以下是我对DW design的一些想法 下次使用C#来实现一下   ETL中Source 的信息       数据提供形式:DB(ORACLE SQLSE ...

  8. 双向广搜 codevs 3060 抓住那头奶牛

    codevs 3060 抓住那头奶牛 USACO  时间限制: 1 s  空间限制: 16000 KB  题目等级 : 黄金 Gold   题目描述 Description 农夫约翰被告知一头逃跑奶牛 ...

  9. [转载]ExtJs4 笔记(5) Ext.Button 按钮

    作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律 ...

  10. HDU 5057 Argestes and Sequence --树状数组(卡内存)

    题意:给n个数字,每次两种操作: 1.修改第x个数字为y. 2.查询[L,R]区间内第D位为P的数有多少个. 解法:这题当时被卡内存了,后来看了下别人代码发现可以用unsigned short神奇卡过 ...