CoolShell Puzzle攻略[更新隐藏剧情]
CoolShell博主陈皓做了一个在线的puzzle很有意思,链接在这里,这里记录一下解题的一些步骤。
Puzzle 0
++++++++[>+>++>+++>++++>+++++>++++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++>+++++++++++++>++++++++++++++>+++++++++++++++>++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>>>>>>>>-.+<<<<<<<<<<<<<<<>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<>>>>>>>>>>>>>>----.++++<<<<<<<<<<<<<<>>>>>>>>>>>>+++.---<<<<<<<<<<<<>>>>>>>>>>>>>>-.+<<<<<<<<<<<<<<>>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<<>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<>>>>>>--.++<<<<<<>>>>>>>>>>>>>.<<<<<<<<<<<<<>>>>>>>>>>>>>>>----.++++<<<<<<<<<<<<<<<>>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<<>>>>>>>>>>>>>>----.++++<<<<<<<<<<<<<<.
如果之前没有听说过变态的编程语言,就让你见识一下。BrainFuck也称BF,是一门只有8个指令构成的图灵完备的语言。CoolShell博主陈皓写过一篇简单的介绍在这里
具体的指令解释不多说了,直接打长这里,把上面的指令粘进去,运行得到下一关的地址:welcome.html
。
Puzzle welcome.html
X * Y
2, 3, 6, 18, 108, ?
What is the meaning of life, the universe and everything?
生命、宇宙以及任何事情的终极答案
这题有两个线索,首先是这串数字,其次是生命、宇宙以及任何事情的终极答案
。数字序列找规律并不复杂,每个数字是前两个数字之积,那么直接用18 * 108
的结果1944
尝试进入下一关,发现只找到了一个答案。第二个答案很有意思,或者说很极客
很宅
,直接google发现和《银河系漫游指南》有关,wiki地址在这里。
用1944 * 42
的答案81648
进入下一关。
Puzzle 81648.html
macb() ? lpcbyu(&gbcq/_\021%ocq\012\0_=w(gbcq)/_dak._=}_ugb_[0q60)s+
放眼望去是Dvorak
键盘,点图片可以看到详细信息。那么意图很明显了,Dvorak
和QWERTY
键盘转换一下看看会怎么样?这里有个在线的转换工具,然后:
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
WTF……搜了一下,这是87年国际C语言混乱大赛的一段代码。C语言了解不多,趁这个机会了解了解戳这里,还有这里,列一些解此题的关键知识点。
- unix关键字相当于
#define unix 1
- 数组的引用,array[num]和num[array]效果相同,所以(unix)["have"] 等于"have"[unix],结果是
a
,ASCII是0x61 0x61 + "fun" - 0x60
相当于对fun
右移0x61
指针再左移0x60
指针,也就是说fun
右称一位,结果是un
- \021是换页,于是
&unix["\021%six\012\0"]
约为&unix["\n%six\n\0"]
,%s
被替为前面的un
,&unix
再跳过了第一个\n
,所以结果是unix
使用unix
,进入下一题。
Puzzle unix.html
微信扫码,得到:
[abcdefghijklmnopqrstuvwxyz] <=> [pvwdgazxubqfsnrhocitlkeymj]
看来是一个简单的替代,请出大shell
echo Wxgcg txgcg ui p ixgff, txgcg ui p epm. I gyhgwt mrl lig txg ixgff wrsspnd tr irfkg txui hcrvfgs, nre, hfgpig tcm liunz txg crt13 ra "ixgff" tr gntgc ngyt fgkgf. | tr "pvwdgazxubqfsnrhocitlkeymj" "abcdefghijklmnopqrstuvwxyz"
得到:
Where there is a shell, there is a way. I expect you use the shell command to solve this problem, now, please try using the rot13 of shell to enter next level.
这里我脑抽了一下,没看仔细以为是用shell命令,尝试各种tr
以及tr xxx xxx
都不行,后来出去跑了个步,回来再读一遍发现是用rot13
转换一下shell
这个字符串,wtf……
echo "shell" | tr "[A-Za-z]" "[N-ZA-Mn-za-m]"
顺利得到下一关地址:furyy
Puzzle furyy.html
啊回文,差点一口老血死在这里……
刚开始思路有点歪,总以为是用cat
再加上什么关键字得出一个单词,cat
的规律其实已经注意到了,只是在纠结于怎么找到后续字母的规律……妈的走的有点远扯着蛋了。
后来又是认真读了下揭示语The answer has been lost in the source
,咦……
Ctrl + Shift + I
打开Chrome的源代码查看工具(IE F12),看见一坨乱码躺在那里,就是它了,很明确,正则表达式。把乱码扔到一个文本文件里,然后执行:
cat data.txt | grep -E "([A-Z])(\d{1})[a-z](\2)(\1)|(\d{1})([A-Z])[a-z](\6)(\5)" -o
输出
E1v1E
4FaF4
9XrX9
O3i3O
0MaM0
4GbG4
M5l5M
0WeW0
Y0s0Y
使用所有中间的字母variables
过关。
Puzzle variables.html
点图片,进入http://fun.coolshell.cn/n/2014
,显示了一个数字,这时候我脑残的用显示的数据作为answer,显然不行。
看到url里的2014
了吗?用网页里的数字替换2014
,然后又出现一个新数据,哦原来是这样……接下来就简单多了,上bash脚本。
#!/bin/bash
baseUrl="http://fun.coolshell.cn/n"
result="2014"
while [[ $result -ne "" ]]; do
result=$(curl -s $baseUrl/$result)
echo "=> $result"
done
输出片断:
=> 32722
=> 13310
...
=> 16626
=> 20446
=> Cool! the next level is "tree"
run.sh: line 6: [[: Cool! the next level is "tree": syntax error in expression (error token is "! the next level is "tree"")
虽然脚本不完美,但是没办法,因为不知道最后会输出什么,这样看来搞出error也是不错的选择……使用tree
过关。
Puzzle tree.html
这道题很直白,纯考功底。先还原二叉树,然后找出最深路径,使用此关键字解密字符串U2FsdGVkX1+gxunKbemS2193vhGGQ1Y8pc5gPegMAcg=
。
由于只有中序的后序的遍历序列,所以需要先从后序序列倒着取出根节点,然后再通过中序序列和后序序列来确立左子树和右子树,此过程递归完成。用js写了一段代码来还原二叉树:
var inOrderSeq = ["T", "b", "H", "V", "h", "3", "o", "g", "P", "W", "F", "L", "u", "A", "f", "G", "r", "m", "1", "x", "J", "7", "w", "e", "0", "i", "Q", "Y", "n", "Z", "8", "K", "v", "q", "k", "9", "y", "5", "C", "N", "B", "D", "2", "4", "U", "l", "c", "p", "I", "E", "M", "a", "j", "6", "S", "R", "O", "X", "s", "d", "z", "t"];
var postOrderSeq = ["T", "V", "H", "o", "3", "h", "P", "g", "b", "F", "f", "A", "u", "m", "r", "7", "J", "x", "e", "w", "1", "Y", "Q", "i", "0", "Z", "n", "G", "L", "K", "y", "9", "k", "q", "v", "N", "D", "B", "C", "5", "4", "c", "l", "U", "2", "8", "E", "I", "R", "S", "6", "j", "d", "s", "X", "O", "a", "M", "p", "W", "t", "z"];
function parseTree(inOrder, postOrder) {
if (inOrder.length == 0 || postOrder.length == 0) {
return null;
}
var root = postOrder[postOrder.length - 1];
var inOrderIndex = inOrder.indexOf(root);
var leftTreeInOrder = inOrder.slice(0, inOrderIndex);
var leftTreePostOrder = postOrder.slice(0, inOrderIndex);
var rightTreeInOrder = inOrder.slice(inOrderIndex + 1);
var rightTreePostOrder = postOrder.slice(inOrderIndex, -1);
var node = {
node: root,
left: parseTree(leftTreeInOrder, leftTreePostOrder),
right: parseTree(rightTreeInOrder, rightTreePostOrder)
};
return node;
}
var tree = parseTree(inOrderSeq, postOrderSeq);
OK,树还原出来了,还需要进行最深路径查找脑中瞬间闪出DFS,完全由于深度优先
四个字。
,这个和深度优先搜索有点像但并不是搜索,通过递归的方式得到最长的路径。顺便提一嘴,BFS(广度优先)借助队列实现,DFS(深度优先)借助栈实现。好了,大学课程回忆完毕,上代码:
function findDeepestPath(selfNode) {
if (selfNode == null) {
return [];
}
if (selfNode.left == null || selfNode.right == null) {
return [selfNode];
}
var leftPathSeq = findDeepestPath(selfNode.left);
var rightPathSeq = findDeepestPath(selfNode.right);
if (leftPathSeq.length > rightPathSeq.length) {
return [selfNode].concat(leftPathSeq);
} else {
return [selfNode].concat(rightPathSeq);
}
}
得到结果zWp8LGn01wxJ7
,保留这个结果,因为下道题还用的到。
echo U2FsdGVkX1+gxunKbemS2193vhGGQ1Y8pc5gPegMAcg= | openssl enc -aes-128-cbc -a -d -pass pass:zWp8LGn01wxJ7
nqueens
,进入下一题。
Puzzle nqueens.html
这个倒是简单粗暴,考回溯算法,求解n后,然后暴力穷举出答案。写求n后解。本想用C#写个小程序,然后生成一个带有所有解txt文件,后来想想何必呢,还是继续用js吧,有node呢……
var crypto = require('crypto');
var passwd = "zWp8LGn01wxJ7";
var target = "e48d316ed573d3273931e19f9ac9f9e6039a4242";
function writeResult(results) {
var resultStr = results.map(function (v) {
return v + 1;
}).join("");
var hashString = passwd + resultStr + "\n";
var sha1 = crypto.createHash('sha1');
sha1.update(hashString)
var digest = sha1.digest('hex') ;
if(digest == target) {
console.log(resultStr);
}
}
function conflict(results, theLocation) {
for (var row = 0; row < results.length; row++) {
var queenLoction = results[row];
if (queenLoction == theLocation) {
return true;
}
var rowDiff = results.length - row;
var locationDiff = Math.abs(theLocation - queenLoction);
if (rowDiff == locationDiff) {
return true;
}
}
return false;
}
function solveQueens(size, results) {
if (typeof results === "undefined") { results = []; }
for (var pos = 0; pos < size; pos++) {
if (conflict(results, pos)) {
continue;
}
// pos is good.
var newResults = results.slice(0);
if (newResults.length == size - 1) {
newResults.push(pos);
writeResult(newResults);
} else {
newResults.push(pos);
solveQueens(size, newResults);
}
}
}
调用solveQueens(9)
并在node下运行即可。
最终的代码合并了计算sha1的部分,注意sha1字符串的最后一定要加\n
,否则是算不出结果的。
顺利拿到下一关入口953172864
。
Puzzle 953172864.html
通过对第一列的观察,发现这是一个26进制/10进制的对应表。那么接下来的总是就是如果将COOLSHELL / SHELL
转化为10进制并转换回26进制对应的字母的问题。
首先COOLSHELL对应的10进制数字分别为3 15 15 12 19 8 5 12 12
,计算公式如下:
3*26^8+15*26^7+15*26^6+12*26^5+19*26^4+8*26^3+5*26^2+12*26^1+12*26^0
使用Excel或Google计算结果为751743486376
。同理,SHELL
结果为8826856
。
接下来将两个数相除的结果85165
(这个数是带小数,但是因为除数和被除数都是整数所以结果也是整数)转回26进制,即辗转相除法
,重复模
26并取余数,得到15 25 21 4
,对应的字母为DUYO
,Bingo进入最后一题。
Puzzle DUYO.html
最后一关是最轻松的一关,从图片得出线索是猪圈密码,然后通过一幅简单的图可轻松逆向出答案:helloworld
.
ps: 通过图形的形状找图中该图形所对应的字母。
pps: 昨天答完的时候通过Top100看到是六十多名,今天再打开发现自己的成绩不见了很奇怪,耗子叔叔我没作弊啊……
=============================
UPDATES:
今天才知道有隐藏剧情……
最后helloworld.html页面填完信息后,会出现一个大大的shutdown图标,查看页面源代码发现:
<span style="color:white">Did you even think vi a image file?
</span>
OK,不要点图片,直接把图片存到本地。然后本能的想到图片里藏有信息。使用文本工具打开,乱码一片。简单粗暴一些,将后缀名改为.zip
,然后解压,会发现有个helloworld.txt
文件,打开,阅读,通过……
CoolShell Puzzle攻略[更新隐藏剧情]的更多相关文章
- DQ8通关攻略
<勇者斗恶龙8>作为勇者斗恶龙系列首次实现3D的一作,游戏无论是从画面.音效还是游戏系统都表现非常不俗,这款游戏也是PS2主机上必玩的一款大作. 作为PS2平台上唯一一款勇者斗恶龙的正传新 ...
- 2048 Puzzle游戏攻略
2048 Puzzle这是目前手机游戏的很火. 在地铁上经常看到的人玩这个游戏. 首先,简介2048 Puzzle游戏. 游戏界面是4X4广场格,每一方格可以放置在数字. 有四种移动数字的方法,向左. ...
- 用C#制作PDF文件全攻略
用C#制作PDF文件全攻略 目 录 前 言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...
- 【转】轻松搞定FTP之FlashFxp全攻略
转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...
- 关于Java高并发编程你需要知道的“升段攻略”
关于Java高并发编程你需要知道的"升段攻略" 基础 Thread对象调用start()方法包含的步骤 通过jvm告诉操作系统创建Thread 操作系统开辟内存并使用Windows ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
- Windows下LATEX排版论文攻略—CTeX、JabRef使用介绍
Windows下LATEX排版论文攻略—CTeX.JabRef使用介绍 一.工具介绍 TeX是一个很好排版工具,在学术界十分流行,特别是数学.物理学和计算机科学界. CTeX是TeX中的一个版本,指的 ...
- IIS 7完全攻略之日志记录配置(摘自网络)
IIS 7完全攻略之日志记录配置 作者:泉之源 [IT168 专稿]除了 Windows 提供的日志记录功能外,IIS 7.0 还可以提供其他日志记录功能.例如,可以选择日志文件格式并指定要记录的请求 ...
- GitHub超详细图文攻略
GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git 分类: 转载2014-03-25 21:10 10641人阅读 评论(2) 收藏 举报 GitHubbr ...
随机推荐
- iOS常用插件
iOS常用插件总结:http://blog.csdn.net/oik_ios/article/details/50251191http://www.jianshu.com/p/d24eea8b405a ...
- 凡聊过必留下痕迹-破解加密的WeChat数据库
有个朋友上门寻求协助,带着她朋友的朋友的手机,说是手机硬件有问题,想把手机内的资料都备份出来,尤其是WeChat的聊天内容…我跟她说,那iTool等工具不就可以帮上忙了吗?没想到她早就试过了, 说iT ...
- JavaScript中的Get和Set访问器
今天要和大家分享的是JavaScript中的Get和Set访问器,和C#中的访问器非常相似. 标准的Get和Set访问器的实现 function Field(val){ this.va ...
- Nginx 日志按天分割
#nginx日志切割脚本 #!/bin/bash #设置日志文件存放目录 logs_path="/home/www.xxx.com/wwwlogs/" #设置pid文件 pid_p ...
- WP8 调用特定API权限不足
1.在解决方案中依次打开 Properties -> WMAppManifest.xml 2.点击功能 3.在左侧功能列表中勾选想要的功能权限.完毕
- C# 集合 — Hashtable 线程安全
基础知识重要吗?真的很重要. 就在笔者与同事聊天中突然同事提出一个问题,让笔都有点乱了手脚(有点夸张),题目是这样的: 问:Hashtable 是线程安全的吗? 答:…… (沉默中,Yes Or No ...
- Check Box Select/Deselect All on Grid
The below function is to be used on a grid with multiple check boxes. Place the code behind a FieldC ...
- HTML 5 Canvas
HTML 5 Canvas HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. <canvas id="myCanvas" width=&q ...
- Silverlight学习之初始化参数
首先需要在Silverlight的宿主页面添加上initParams,如 <param name="initParams" value="key1=jerry,ke ...
- 在c#中使用mongo-csharp-driver操作mongodb
1)下载安装 下载地址:http://github.com/mongodb/mongo-csharp-driver/downloads 编译之后得到两个dll MongoDB.Driver.dll:顾 ...