资讯专栏INFORMATION COLUMN

一步一步写一个简单的js版quine程序

AJie / 660人阅读

摘要:感觉挺有意思的,于是打算自己用写一个试试。为有趣起见,准备从一个打印本站域名的额外功能开始这个命令可以在控制栏打印出一行。接下来我准备一步一步改造这个命令,直至达成的目标。注意到源码里外用了不同的引号,这是为了规避转义符。

原文自转->这里

早上看了justjavac大大的一篇文章:javascript 的 quine 程序升级版,了解了一下所谓quine程序的概念:

  

一个 quine 是一个计算机程序,它不接受任何输入,且唯一的输出就是自身的源代码。

感觉挺有意思的,于是打算自己用js写一个试试。

首先确定输出方式为控制台,即通过console.log输出。

为有(guang)趣(gao)起见,准备从一个“打印本站域名”的“额外功能”开始:

console.log("perichr.org")

这个命令可以在控制栏打印出一行perichr.org。接下来我准备一步一步改造这个命令,直至达成quine的目标。

首先试着打印上面这个命令:

console.log("console.log("perichr.org")")

这样就在控制栏打印了一行console.log("perichr.org")。注意到源码里外用了不同的引号,这是为了规避转义符。

对了,别忘了需要执行自己,那么有:

console.log("perichr.org");console.log("console.log("perichr.org")")

很好,这样即执行了“额外功能”,又打印了自己的源代……不对!压根没有打印自己的源代码对吧!
从简单的入手,不考虑打印完整源代码,先想想要怎样能在执行一个功能的同时打印功能代码呢?打印的是字符串,执行的是js源码……想到什么了?对了,eval

p="console.log("perichr.org")";eval(p);console.log(p)

很好,这次完美地打印了perichr.orgconsole.log("perichr.org")。要注意的是,这里的变量p没有做声明,严格模式下是通不过的哟!

不过这还远远不够!来做一点小调整:

p="console.log("perichr.org");console.log(p)";eval(p)

发现了吗?这次输出了perichr.orgconsole.log("perichr.org");console.log(p)!进化了!接下来先讨个巧,利用 赋值表达式返回右值 的小技巧来简化一下代码,毕竟代码越精简心理压力越小嘛……

eval(p="console.log("perichr.org");console.log(p)")

接下来怎么办呢……来对比下上面的源码和输出的代码:console.log("perichr.org");console.log(p),其实已经很接近了有木有!输出码就是缺少了头eval(p="和尾")!来,补上!

eval(p="console.log("perichr.org");console.log("eval(p=""+p+"")")")

在补的时候就应该已经注意到了一个问题:转义符!这里已经无法避免转义符了!来看看输出的代码:eval(p="console.log("perichr.org");console.log("eval(p=""+p+"")")")

真好,已经十分接近了对吧!但还是有一点小问题:没错,转义符!输出时源码中的"被转义成了"!怎么办?那就要把文本中的"反转义为"!怎么转?可以使用""".replace(/"/g,""")这种方式。考虑到文本要在p的赋值时转义,那么就需要手动反转义为:".replace(/"/g,""")"。接下来把它插入源码中:

eval(p="console.log("perichr.org");console.log("eval(p=""+p.replace(/"/g,""")+"")")")

等等……好像有什么不对?我刚才是不是把一大波 有用的反斜杠 加入源代码了?要知道,这货也是会被转义的啊!!怎么办?好嘛,来改造下反转义代码,这回单引号和反斜杠都要反转义一下:.replace(/["]/g,"$&"),这里的$&是指返回匹配字符串。手动反转义:.replace(/["]/g,"$&"),再来一次:

eval(p="console.log("perichr.org");console.log("eval(p=""+p.replace(/["]/g,"$&")+"")")")

在控制台试一试……成功!完美!强力!分毫不差地返回了自身!任务圆满完成!

怎么样,看起来很高大上的东西,其实入门很简单吧?

有人问,费劲心机写这么个东西,有啥意义?嘛,这个世界不是为了“某些人所谓的意义”而存在的。世界存在的意义在于“世界存在”这个现象本身;我折腾这个东西的意义也就在于“折腾代码”这件事本身。我觉得我获得了一些有意义的东西。你说呢?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78119.html

相关文章

  • 小白成长日记:步一步写个轮播图插件

    摘要:并不是所有人写的代码或者插件都适合小白使用,比如这是一个的滚动插件,大多数人使用了之后发现滚动不了,去作者提,其实是他们并不懂滚动的原理。 最近在这里看了一篇关于面试的文章《回顾自己三次失败的面试经历》,作者三次倒在了轮播图上。囧,所以我也写个轮播图看看。这次是用jQuery写的,因为最近一直在研究jQuery插件的写法,所以用jQuery写的,而且我发现,我vue用太多,完全不熟悉d...

    notebin 评论0 收藏0
  • javascript quine 程序(升级

    摘要:但是,既然我博客的关于页面都已经折腾出升级版了,那么我们就再折腾一个出来。程序的升级版动态的。最后在附赠一个,这个其实不能算是严格的程序可以滚动的地球仪 本文来自我的博客:http://justjavac.com/javascript/2013/10/11/javascript-quine-plus.html Quine 以哲学家 Willard van Orman Quine (1...

    nidaye 评论0 收藏0
  • 步一步搭建前端监控系统:如何将网页截图上报?

    摘要:目前已经在运行的线上前端监控系统代码和讲解都放在这篇文章里监控系统介绍及代码用户对前端程序员来说,就是一个黑匣子。 摘要: 通过录屏或者截图,快速复现BUG场景。 作者:一步一个脚印一个坑 原文:搭建前端监控系统(备选)Js截图上报篇 Fundebug经授权转载,版权归原作者所有。 PS:本文关于Fundebug录屏功能的内容有些不准确的地方,比如录屏并非通过截图实现的,录屏插件...

    Martin91 评论0 收藏0
  • 步一步搭建前端监控系统:如何记录用户行为?

    摘要:摘要通过记录用户行为,快速复现场景。这是搭建前端监控系统的第二章,主要是介绍如何统计报错,跟着我一步步做,你也能搭建出一个属于自己的前端监控系统。 摘要: 通过记录用户行为,快速复现BUG场景。 作者:一步一个脚印一个坑 原文:搭建前端监控系统(备选)用户行为统计和监控篇(如何快速定位线上问题) Fundebug经授权转载,版权归原作者所有。 一步一步搭建前端监控系统系列博客: ...

    tolerious 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<