探秘 JavaScript 中的六个字符

DeandreTabe 7年前
   <p style="text-align:center"><img src="https://simg.open-open.com/show/8e46fbea515b5aad1a88459cdb082f4c.jpg"></p>    <p> </p>    <p>JavaScript 是一个奇怪而有趣的语言,我们可以写一些疯狂却仍然有效的代码。它试图帮助我们把事情转换到基于我们如何对待他们的特定类型。</p>    <p>如果我们添加一个字符串,JavaScript会假定我们希望为文本形式表示,所以将它转换为一个字符串。如果我们添加一个正负前缀符号,JavaScript会假定我们希望为数值形式表示,如果可能的话,对我们来说并将字符串转换为一个数字。如果我们添加一个否定符号,JavaScript会将将字符串转换为一个布尔值。</p>    <p>我们可以使用Javascript中 [ , ] , ( , ) , !  and  + 这六个符号写一些神奇的代码。如果你现在不是在手机,你可以打开浏览器的控制台,你可以将任何代码示例粘贴到控制台,并且代码值为true。</p>    <p>让我们从最基本的开始,要记住一些黄金规则:</p>    <p>! 后面跟的字符会被转换成布尔值</p>    <p>+ 后面跟的字符会被转换成数值</p>    <p>[] 后面跟的字符会被转换成字符串</p>    <p>来看下面的例子:</p>    <pre>  <code class="language-javascript">![] === false  +[] === 0  []+[] === ""</code></pre>    <p>另一件事你应该知道的是,它可以从字符串使用方括号检索特定的字母,像这样:</p>    <pre>  <code class="language-javascript">"hello"[0] === "h"</code></pre>    <p>还记得可以使多个数字号码通过添加字符串表示在一起,然后把整个表达式转换成一个数字:</p>    <pre>  <code class="language-javascript">+("1" + "1") === 11</code></pre>    <p>我们们继续把一些东西结合在一起得到字母a</p>    <pre>  <code class="language-javascript">![] === false  ![]+[] === "false"  +!![] === 1  ------------------------  (![]+[])[+!![]] === "a"  // same as "false"[1]</code></pre>    <p>举一反三!</p>    <p>我们可以通过true 和 false得到相似的字母 a , e , f , l , r , s , t , u ,那么我们可以从其他地方得到的字母吗?</p>    <p>我们可以通过一些特别的式子如[][[]]得到undefined,利用我们上面讲到的黄金法则得到另外的字母 d , i  和  n 。</p>    <pre>  <code class="language-javascript">`[][[]] + [] === "undefined"`</code></pre>    <p>到目前为止,利用我们已经获得的所有字母,我们可以拼 fill ,  filter  和  find 。当然也有一些其他的单词,我们也可以拼写,但这些单词最重要的是,他们都是数组的方法。这意味着他们是数组对象的一部分,可以直接调用数组实例,如: [2,1].sort() 。</p>    <p>现在,了解JavaScript的另一件重要的特性是一个对象的属性可以通过点符号.或方括号[]访问。上述数组方法是数组对象本身的属性,我们可以使用方括号代替点符号调用这些方法。</p>    <p>所以[2,1]["sort"]() 等效于 [2,1].sort().</p>    <p>我们继续看看,当我们试图使用一个数组的方法会发生什么,我们可以使用到目前为止我们拼写的但没有调用的字母。</p>    <pre>  <code class="language-javascript">[]["fill"]</code></pre>    <p>这会得到function fill() { [native code] },我们可以把这个方法头作为一个字符串再次使用我们的黄金法则:</p>    <pre>  <code class="language-javascript">[]["fill"]+[] === "function fill() { [native code] }"</code></pre>    <p>所以现在我们又得到其他的字符: c , o , v , ( , ) , { , [ , ] , } 。</p>    <p>随着我们新得到的c和o,我们现在可以形成constructor这个单词。构造函数是一个方法,所有JS对象仅返回自己的构造函数。</p>    <p>到目前为止我们已经处理的对象,我们可以得到它用字符串表示的构造器函数:</p>    <pre>  <code class="language-javascript">true["constructor"] + [] === "function Boolean() { [native code] }"      0["constructor"] + []    === "function Number() { [native code] }"    ""["constructor"] + []   === "function String() { [native code] }"  []["constructor"] + []   === "function Array() { [native code] }"  ({})["constructor"] + [] === "function Object() { [native code] }"</code></pre>    <p>通过这些式子,我们可以将下面的字符加入到我们的库中: B , N , S , A , O , m , b , g , y , j 。</p>    <p>现在我们可以构造一个我们可以使用方括号的函数"toString"`,我们可以这样调用:</p>    <pre>  <code class="language-javascript">(10)["toString"]() === "10"</code></pre>    <p>使用我们的黄金法则,我们已经可以将任何我们想要转换成一个字符串,但是上面这个式子怎么用呢?</p>    <p>好吧,我告诉你,Number类型的toString方法有一个称为radix(“基数”)的秘密的论点。它可以将数值在转换为一个字符串之前先经过基数换算,像这样:</p>    <pre>  <code class="language-javascript">(12)["toString"](10) === "12"  // 十进制  (12)["toString"](2) === "1100" // 二进制  (12)["toString"](8) === "14"   // 八进制  (12)["toString"](16) === "c"   // 十六进制</code></pre>    <p>但是为什么基数只写到16?最大值是36,包括所有的字符0-9 和 a-z,所以现在我们可以得到任何我们想要的字母数字:</p>    <pre>  <code class="language-javascript">(10)["toString"](36) === "a"  (35)["toString"](36) === "z"</code></pre>    <p>太棒了!但是其它符号如标点符号和大写字母呢?我们接着深入探索。</p>    <p>这取决于你的JS执行时,它可能会或可能不会访问特定的预定义的对象或数据。如果你在浏览器中运行它,那么你可以访问一些存在的HTML包装器方法。</p>    <p>例如,bold是一个包装在<>标签中的字符串方法。</p>    <pre>  <code class="language-javascript">"test"["bold"]() === "<b>test</b>"</code></pre>    <p>通过这个我们得到 <> 和 / 两个字符。</p>    <p>你可能听说过escape方法,它主要将字符串转换为一个URI友好的格式,可以让简单的浏览器解释。如果我们传递一个空格字符,我们得到的"%20"。</p>    <p>这里有一个工具可以自动将每个字符自动转换。 </p>    <p><strong>为什么这几个字符有用?</strong></p>    <p>它不是易趣网做的一些不好的事情,不久前允许卖家将执行JS在页面中使用只能使用这些字符,但它是一个相当罕见的攻击向量。有些人说混淆,但事实上,有更好的方法混淆。</p>    <p>最后,希望你会喜欢本次探秘之旅。</p>    <p> </p>    <p> </p>    <p> </p>    <p>来自:http://mp.weixin.qq.com/s/io0i2ukw91sbJVKlGdEduA</p>    <p> </p>