<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>LEAFER x LAB</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://leaferx.online/"/>
  <updated>2019-09-02T18:10:54.375Z</updated>
  <id>https://leaferx.online/</id>
  
  <author>
    <name>LEAFERx</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>基石#2 | Unicode 漫谈</title>
    <link href="https://leaferx.online/2019/09/03/cornerstone-2-unicode/"/>
    <id>https://leaferx.online/2019/09/03/cornerstone-2-unicode/</id>
    <published>2019-09-03T15:21:37.000Z</published>
    <updated>2019-09-02T18:10:54.375Z</updated>
    
    <content type="html"><![CDATA[<p>这是 Cornerstone 基石系列的第二篇，主题是 Unicode 与 UTF。</p><a id="more"></a><hr><h1 id="开始前的一些准备"><a class="header-anchor" href="#开始前的一些准备">¶</a>开始前的一些准备</h1><p>首先我们需要在脑海中记熟一些二进制的转换关系，以便直观地理解 Unicode。</p><table><thead><tr><th>储存大小</th><th>范围</th><th>十进制大小</th></tr></thead><tbody><tr><td>4 bit</td><td>0x0 - 0xF</td><td>2<sup>4</sup> = 16</td></tr><tr><td>1 Byte</td><td>0x00 - 0xFF</td><td>2<sup>8</sup> = 256</td></tr><tr><td>2 Bytes</td><td>0x0000 - 0xFFFF</td><td>2<sup>16</sup> = 65,536</td></tr></tbody></table><p>其次，我们需要了解字节序。字节序分为大端序（Big-Endian, BE）与小端序（Little-Endian, LE）。只需要记住，大端序的最高位字节存储在最低的内存地址处，而小端序的最高字节存储在最高的内存地址处。</p><p>以下是存储 32 位整数 0x12345678 的例子：</p><table><thead><tr><th style="text-align:center">内存地址</th><th style="text-align:center">大端序</th><th style="text-align:center">小端序</th></tr></thead><tbody><tr><td style="text-align:center">0x03</td><td style="text-align:center">0x12</td><td style="text-align:center">0x78</td></tr><tr><td style="text-align:center">0x02</td><td style="text-align:center">0x34</td><td style="text-align:center">0x56</td></tr><tr><td style="text-align:center">0x01</td><td style="text-align:center">0x56</td><td style="text-align:center">0x34</td></tr><tr><td style="text-align:center">0x00</td><td style="text-align:center">0x78</td><td style="text-align:center">0x12</td></tr></tbody></table><h1 id="什么是-unicode"><a class="header-anchor" href="#什么是-unicode">¶</a>什么是 Unicode</h1><blockquote><p>Unicode（中文：万国码、国际码、统一码、单一码）是电脑科学领域里的一项<strong>业界标准</strong>。它对世界上大部分的文字系统进行了整理、编码，使得电脑可以用更为简单的方式来呈现和处理文字。<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p></blockquote><p>需要注意的是，Unicode 准确来说是一种<strong>字符集</strong>，而与我们日常中使用的各种编码有所区别。Unicode 给每一个它所管辖的字符分配了一个唯一而确定的 ID（二进制整数），但并没有规定这些字符应该如何储存、传输。规定这些字符如何的则是 UTF（Unicode Transformation Format）标准，即 UTF 是对 Unicode 的编码。</p><h1 id="unicode-的组成"><a class="header-anchor" href="#unicode-的组成">¶</a>Unicode 的组成</h1><h2 id="代码点-code-point-code-position"><a class="header-anchor" href="#代码点-code-point-code-position">¶</a>代码点（Code Point / Code Position）</h2><p>代码点用来称呼分配给字符的整数。例如，在 Unicode 中字符“爱”的代码点为 U+7231<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。在表示代码点时，习惯用 U+ 作为前缀，然后紧接该代码点的十六进制数字。</p><h2 id="代码空间-code-space"><a class="header-anchor" href="#代码空间-code-space">¶</a>代码空间（Code Space)</h2><p>所有代码点组成集合称为代码空间。Unicode 的代码空间范围为 U+0000 到 U+10FFFF，一共 1,114,112 个代码点。截至本文写作时间，Unicode 最新标准 12.1.0<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> 已经给 137,929 个字符分配了代码点。</p><p><em>P.S. Unicode 12.0.0 至 12.1.0 只新增了一个字符，即日本新年号令和的合字（U+32FF）<sup class="footnote-ref"><a href="#fn3" id="fnref3:1">[3]</a></sup>。</em></p><h2 id="平面-plane"><a class="header-anchor" href="#平面-plane">¶</a>平面（Plane）</h2><p>Unicode 将 U+0000 到 U+10FFFF 分割为 17 个平面，每个平面拥有 65,536 个码点（即 2 字节）。其中，0 号平面称为基本多文种平面（Basic Multilingual Plane, BMP），其他平面则成为补充平面 / 辅助平面（Supplementary Plane）。不同平面的具体划分和作用如下<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>：</p><table><thead><tr><th>平面</th><th>始末字符值</th><th>中文名称</th><th>英文名称</th></tr></thead><tbody><tr><td>0 号平面</td><td>U+0000 - U+FFFF</td><td>基本多文种平面</td><td>Basic Multilingual Plane, BMP</td></tr><tr><td>1 号平面</td><td>U+10000 - U+1FFFF</td><td>多文种补充平面</td><td>Supplementary Multilingual Plane, SMP</td></tr><tr><td>2 号平面</td><td>U+20000 - U+2FFFF</td><td>表意文字补充平面</td><td>Supplementary Ideographic Plane, SIP</td></tr><tr><td>3 号平面</td><td>U+30000 - U+3FFFF</td><td>表意文字第三平面（未正式使用）</td><td>Tertiary Ideographic Plane, TIP</td></tr><tr><td>4~13 号平面</td><td>U+40000 - U+DFFFF</td><td>（尚未使用）</td><td></td></tr><tr><td>14 号平面</td><td>U+E0000 - U+EFFFF</td><td>特别用途补充平面</td><td>Supplementary Special-purpose Plane, SSP</td></tr><tr><td>15 号平面</td><td>U+F0000 - U+FFFFF</td><td>保留作为私人使用区（A区）</td><td>Private Use Area-A, PUA-A</td></tr><tr><td>16 号平面</td><td>U+100000 - U+10FFFF</td><td>保留作为私人使用区（B区）</td><td>Private Use Area-B, PUA-B</td></tr></tbody></table><p>BMP 是 Unicode 中最重要的平面，常用的字符都定义在这个平面中。</p><blockquote><p>在BMP中定义的代码点包括<sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>：</p><ul><li><strong>ASCII</strong> 共 128 个字符，占据了 BMP 的前 128 个代码点</li><li><strong>ISO-8859-1</strong> 共 256 个字符，占据了 BMP 的前 256 个代码点</li><li><strong>CJK Unified Ideographs</strong> 占据 BMP 大约 1/3，定义了两万多个汉字，其中前 20,902 个汉字是按照《康熙字典》里笔画顺序排列的</li><li><strong>Surrogate Code Points</strong> 从 U+D800 到 U+DBFF 的 1024 个代码点是 High-surrogate 代码点，从 U+DC00 到 U+DFFF 的 1024 个代码点是 Low-surrogate 代码点。这 2048 个代码点并不是有效的字符代码点，它们是为 UTF 编码保留的。一个 High-surrogate 代码点和一个 Low-surrogate 代码点组成一个代理对（Surrogate Pair），可以在 UTF-16 里编码 BMP 之外的某个代码点。</li></ul></blockquote><p>以上便是 Unicode 的一些介绍。</p><p>详细的标准定义请参考 <a href="https://unicode.org" rel="external nofollow noopener noreferrer" target="_blank">https://unicode.org</a>。</p><p>以及推荐一个用来查询 Unicode 字符的网站 <a href="https://unicode-table.com/cn/" rel="external nofollow noopener noreferrer" target="_blank">https://unicode-table.com/cn/</a>，无聊的时候翻翻还是特别好玩der。</p><h1 id="utf-编码"><a class="header-anchor" href="#utf-编码">¶</a>UTF 编码</h1><p>以下将介绍三种 UTF 格式，即 UTF-8、UTF-16 和 UTF-32。</p><h2 id="utf-32"><a class="header-anchor" href="#utf-32">¶</a>UTF-32</h2><p>最直观的一个实现方法就是将 Unicode 代码点直接存储。UTF-32 就是这样的一种实现，它将每个字符都存储为 4 字节的代码点，这样的好处是不需要进行解析就可以直接将 UTF-32 存储的字符进行翻译，然而因为常用的字符几乎都存在于 BMP 中，所以这样的实现方案是对空间的极大浪费。目前，UTF-32 几乎没有任何实际用途，甚至于 HTML5 标准明文规定网页不得使用 UTF-32 存储<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup>。</p><h2 id="utf-8"><a class="header-anchor" href="#utf-8">¶</a>UTF-8</h2><p>UTF-8 是一种可变长的字符编码，其设计兼顾了存储效率和兼容性，是目前使用最为广泛的一种 UTF 编码。UTF-8 使用 1 到 4 字节来编码 Unicode（UTF-8 编码的最高上限是 6 字节，而事实上 4 字节就已经足够完成 Unicode 代码空间的编码）。其中，1 字节的 UTF-8 编码完全与 ASCII 编码兼容。</p><p>UTF-8 的编码规则很简单：</p><ul><li>对于单字节符号，该字节的第一位设为 0，后面 7 位为该符号的 Unicode 代码点。</li><li>对于 n（n &gt; 1） 字节的符号，第一个字节的前 n 位设为 1， 第 n + 1 位设为 0，之后的字节前两位一律设为 10，其余没有提及的二进制位为该符号的 Unicode 代码点。</li></ul><table><thead><tr><th>Unicode 范围</th><th>UTF-8</th></tr></thead><tbody><tr><td>U+0000 - U+007F</td><td>0xxxxxxx</td></tr><tr><td>U+0080 - U+07FF</td><td>110xxxxx 10xxxxxx</td></tr><tr><td>U+0800 - U+FFFF</td><td>1110xxxx 10xxxxxx 10xxxxxx</td></tr><tr><td>U+010000 - U+10FFFF</td><td>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</td></tr></tbody></table><p>还是以字符“爱”作为例子，U+7231 在 U+0800 - U+FFFF 范围内，所以采用 3 个字节进行编码。U+7231 转换成二进制为 01110010 00110001‬，填入 1110xxxx 10xxxxxx 10xxxxxx 可以得到 1110<strong>0111</strong> 10<strong>001000</strong> 10<strong>110001</strong>，转换成十六进制为 E7 88 B1‬，即“爱&quot;的 UTF-8 编码为 <strong>E7 88 B1</strong>。</p><p>有一个问题是，之前提到过字节序，那么 UTF-8 的存储是否受到字节序影响呢？答案是否定的。UTF-8 的存储其实是以单字节为单元的，应用程序在解析和存储 UTF-8 编码时，应该一个字节一个字节地进行处理，所以 UTF-8 的存储与字节序无关。然而，上面的 UTF-32 和接下来讲到的 UTF-16，其存储单元分别为四个字节和两个字节，因此和字节序有关。</p><h2 id="utf-16"><a class="header-anchor" href="#utf-16">¶</a>UTF-16</h2><p>UTF-16 同样是一种可变长的字符编码，其使用 2 到 4 字节来编码 Unicode。</p><p>还记得上文中提到的范围为 U+D800 至 U+DFFF 的代理代码点吗？这些代码点便是用来实现 UTF-16 编码的。</p><p>UTF-16 的编码规则如下：</p><ul><li><p>对于在 U+0000 至 U+D7FF 和 U+E000 至 U+FFFF 范围内的代码点（即 BMP 内所有除了代理代码点之外的代码点），UTF-16 将其代码点直接存储为 2 字节的内容。</p></li><li><p>对于在 U+10000 至 U+10FFFF 范围内的代码点（即所有辅助平面的代码点），UTF-16 将其编码为一对 2 字节共 4 字节的内容，其内容的生成方法如下：</p><ul><li><p>代码点减去 0x10000，得到的值范围处于 0x00000 至 0xFFFFF内，共 20 比特。</p></li><li><p>该值的前 10 比特被加上 0xD800，得到第一个 2 字节的内容，称之为前导代理（Lead Surrogates）。</p></li><li><p>该值的后 10 比特被加上 0xDC00，得到第二个 2 字节的内容，称之为后尾代理（Trail Surrogates）。</p></li></ul></li></ul><p>以上的叙述过于繁杂，我们还是以字符“爱”为例，对其进行 UTF-16 编码。</p><p>代码点 U+7321 处于 BMP 中，且不是代理代码点，所以其 UTF-16 的编码直接为 <strong>73 21</strong>。</p><p>我们再以代码点 U+1F600（字符为 emoji 笑脸 “😀”）为例。先将其减去 0x10000，得到 0xF600，二进制为 0000111101 1000000000，前 10 比特转换成十六进制为 0x003D，加上 0xD800 等于 0xD83D，后 10 比特转换成十六进制为 0x0200，加上 0xDC00 等于 0xDE00，所以其 UTF-16 的编码为 <strong>D8 3D DE 00</strong>。作为比较，其 UTF-8 的编码为 <strong>F0 9F 98 80</strong>（编码过程请读者自行推导）。</p><p>需要注意的是，以上两个 UTF-16 编码都是小端序编码，即 UTF-16LE。作为比较，其大端序编码（UTF-16BE）分别为 <strong>21 73</strong> 和 <strong>3D D8 00 DE</strong>。请读者特别注意 UTF-16 的编码单元为 2 字节，所以其 4 字节编码在大端序和小端序的区别只是编码单元内颠倒，前导代理和后尾代理的顺序并没有改变。</p><p><em>思考题：UTF-16 的设计如何识别一个字符编码到底是 2 字节还是 4 字节？</em></p><p>值得一提的是，将 UTF-8 与 UTF-16 进行对比可以发现，对于常用的汉字（CJK 字符集），UTF-16 将其编码为 2 个字节，而 UTF-8 则大多将其编码为 3 个字节。因此，对于汉字（CJK 字符集）集中的文本，UTF-16 编码后的大小要显著小于 UTF-8。</p><h2 id="byte-order-mark-bom"><a class="header-anchor" href="#byte-order-mark-bom">¶</a>Byte Order Mark (BOM)</h2><p>UTF-16 和 UTF-32 有字节序的问题，那么如何分辨一段 UTF-16 或 UTF-32 编码的文本究竟是大端序还是小端序呢？这就需要在文本之前附加一段 BOM。为了能够兼容不支持解析 BOM 的编辑器，Unicode 标准采用了零宽度无端空白字符（U+FEFF，目前已弃用）作为 BOM<sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup>（然而事实上 BOM 还是造成了很大的兼容性问题）。因为 UTF-8 并没有字节序的问题，其也不需要 BOM，然而 Unicode 也还是为其设计了一个 BOM，用来作为可选的 UTF-8 编码标识。</p><table><thead><tr><th>编码</th><th>BOM</th></tr></thead><tbody><tr><td>UTF-8</td><td>EF BB BF</td></tr><tr><td>UTF-16LE</td><td>FE FF</td></tr><tr><td>UTF-16BE</td><td>FF FE</td></tr><tr><td>UTF-32LE</td><td>00 00 FE FF</td></tr><tr><td>UTF-32BE</td><td>FF FE 00 00</td></tr></tbody></table><p>以上便是对 Unicode 和 UTF 的简单介绍。更多细节性的东西请参考其标准定义（其实读读这些定义文档还是十分有趣的）。</p><h1 id="unicode-与-jacascript"><a class="header-anchor" href="#unicode-与-jacascript">¶</a>Unicode 与 JacaScript</h1><p><em>Unicode 在 JavaScript 存储时的字节序问题略过不表，将在以后有关 Buffer 的文章中说明。</em></p><p>由于历史原因，在 ES6 之前 JavaScript 只支持 UCS-2 编码（即 UTF-16 的 BMP 部分），因此对于 4 字节的 UTF-16 字符，JavaScript 会将其识别为两个字符。所幸，ES6 针对这个问题进行了优化，目前 ES6 已经较为完善地支持 UTF-16 了（然而由于兼容性问题，4 字节的 UTF-16 字符在 JavaScript 中作为字符串的长度仍然为 2）<sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup>。</p><p>有关 ES6 针对 Unicode 的支持网上各方面的资料已经叙述的十分详细了，而且这方面的内容在日常码代码时很少用到，这里也就略过，有兴趣的读者可以自行搜索。这里只说一点，ES6 在字符串中提供了 <code>\u{}</code> 转义，例子如下：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'😀'</span> === <span class="string">'\u&#123;1F600&#125;'</span></span><br></pre></td></tr></table></figure><hr><h1 id="写在最后"><a class="header-anchor" href="#写在最后">¶</a>写在最后</h1><p>这篇文章写得比较仓促，所以相关的知识也比较简略，大概算是一个用于科普的随手记，主要是写给自己看的，以防自己忘记这些基础的东西。</p><p>同时这篇文章与 JavaScript 和 Node.js 的关系不大。其实本来计划的第二篇是直接写有关 Buffer 等 JavaScript 和 Node.js 中的二进制数据处理知识，然而在学习相关知识的过程中发现自己对 Unicode 毫无了解，就打算临时改变主题，了解了一下 Unicode。其实 Unicode 涉及到的知识和历史十分庞杂，这篇文章所写的也只是基础中的基础，毕竟字符集和字符编码是从计算机出现伊始至今都是一个十分重要的问题，如果要详细叙述，写成几本专著都不为过。不过本文的知识用于应付日常码代码也应该还是足够，对于编程和运维中的编码问题也能够提供一些解决思路。</p><p>以及，之后的基石系列考虑到时间和精力问题，可能在叙述方面会变得越来越精简，毕竟这个系列的初衷还是为了写给自己看，督促自己夯实基础、努力学习的。当然如果有什么问题和建议，欢迎与我联系（评论万年不看，建议邮箱 / QQ）。</p><p>下一篇的预计完成时间应该在国庆期间，当然能提早会尽量提早。</p><p>有关其他的项目和坑，仍然在整理当中，欢迎继续关注.jpg 我们下一篇见！</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p><a href="https://zh.wikipedia.org/zh-hans/Unicode" rel="external nofollow noopener noreferrer" target="_blank">https://zh.wikipedia.org/zh-hans/Unicode</a> <a href="#fnref1" class="footnote-backref">↩</a></p></li><li id="fn2" class="footnote-item"><p><a href="https://unicode-table.com/cn/7231/" rel="external nofollow noopener noreferrer" target="_blank">https://unicode-table.com/cn/7231/</a> <a href="#fnref2" class="footnote-backref">↩</a></p></li><li id="fn3" class="footnote-item"><p><a href="http://www.unicode.org/versions/Unicode12.1.0/" rel="external nofollow noopener noreferrer" target="_blank">http://www.unicode.org/versions/Unicode12.1.0/</a> <a href="#fnref3" class="footnote-backref">↩</a> <a href="#fnref3:1" class="footnote-backref">↩</a></p></li><li id="fn4" class="footnote-item"><p><a href="https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84" rel="external nofollow noopener noreferrer" target="_blank">https://zh.wikipedia.org/wiki/Unicode字符平面映射</a> <a href="#fnref4" class="footnote-backref">↩</a></p></li><li id="fn5" class="footnote-item"><p><a href="https://blog.csdn.net/zxhoo/article/details/38819517" rel="external nofollow noopener noreferrer" target="_blank">https://blog.csdn.net/zxhoo/article/details/38819517</a> <a href="#fnref5" class="footnote-backref">↩</a></p></li><li id="fn6" class="footnote-item"><p><a href="http://www.ruanyifeng.com/blog/2014/12/unicode.html" rel="external nofollow noopener noreferrer" target="_blank">http://www.ruanyifeng.com/blog/2014/12/unicode.html</a> <a href="#fnref6" class="footnote-backref">↩</a></p></li><li id="fn7" class="footnote-item"><p><a href="https://zh.wikipedia.org/wiki/%E4%BD%8D%E5%85%83%E7%B5%84%E9%A0%86%E5%BA%8F%E8%A8%98%E8%99%9F" rel="external nofollow noopener noreferrer" target="_blank">https://zh.wikipedia.org/wiki/位元組順序記號</a> <a href="#fnref7" class="footnote-backref">↩</a></p></li><li id="fn8" class="footnote-item"><p><a href="http://www.ruanyifeng.com/blog/2014/12/unicode.html" rel="external nofollow noopener noreferrer" target="_blank">http://www.ruanyifeng.com/blog/2014/12/unicode.html</a> <a href="#fnref8" class="footnote-backref">↩</a></p></li></ol></section>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这是 Cornerstone 基石系列的第二篇，主题是 Unicode 与 UTF。&lt;/p&gt;
    
    </summary>
    
      <category term="Cornerstone 基石系列" scheme="https://leaferx.online/categories/Cornerstone-%E5%9F%BA%E7%9F%B3%E7%B3%BB%E5%88%97/"/>
    
    
      <category term="Node.js" scheme="https://leaferx.online/tags/Node-js/"/>
    
      <category term="JavaScript" scheme="https://leaferx.online/tags/JavaScript/"/>
    
      <category term="Conterstone" scheme="https://leaferx.online/tags/Conterstone/"/>
    
      <category term="基石" scheme="https://leaferx.online/tags/%E5%9F%BA%E7%9F%B3/"/>
    
      <category term="基础" scheme="https://leaferx.online/tags/%E5%9F%BA%E7%A1%80/"/>
    
      <category term="Fundamental" scheme="https://leaferx.online/tags/Fundamental/"/>
    
      <category term="Unicode" scheme="https://leaferx.online/tags/Unicode/"/>
    
      <category term="UTF-8" scheme="https://leaferx.online/tags/UTF-8/"/>
    
  </entry>
  
  <entry>
    <title>一份碎碎念</title>
    <link href="https://leaferx.online/2019/08/18/talks-20190818/"/>
    <id>https://leaferx.online/2019/08/18/talks-20190818/</id>
    <published>2019-08-18T05:30:00.000Z</published>
    <updated>2019-08-18T05:35:35.776Z</updated>
    
    <content type="html"><![CDATA[<center>大家好，万年咕咕咕又回来了。</center><a id="more"></a><hr><p>唉不知道从啥说起。本来还说基石系列两周一更，不存在的（笑）。从五月开始一路忙一路咕咕。之前也说暑学期更两篇就奖励自己一个手办（啊啊啊啊啊我的珞珈），结果 dt 课忙到疯只得又咕咕，到现在才逐渐空下来。</p><p>讲讲消失的时间里做的一些事情吧。四月底去了 Bitrun 2019 比赛，做了个车辆网+区块链的项目，拿了创新大奖，不慎掉入币圈（（。然后也是因为做的比较好，受到赞助方 <a href="cpchain.io">Cpchain</a> 的邀请去他们公司逛了一圈谈了很多吃了顿饭，对他们这样区块链物联网的方向还是挺有兴趣的。然后回学校就开始期中考试，期中考试考完就开始期末考试和期末论文（…）。哦对了，五月底在当当买了一大堆书（我突然想起来还有书单这么一个坑……）。英语课论文写了开源软件运动，还是挺好玩的。考试之间同时参加了网易 mini 游戏制作比赛，算是入坑了一把 unity，然而连初赛也没有过（笑）。期末考试完六月就快过完了（数分考炸，GPA瞬间消失术）。哦对了，还有录音机没电的四级考试，至今没有勇气查成绩（话说成绩出来了吗我都不知道）。接下来是暑学期，上 dt（design thinking，设计思维）。原本以为终于空了下来有时间了毕竟整个学期就一节课，没想到肝得要死。最终做了一个可穿戴报警装置（本来是想用导电线把原件缝在布上的但是实在来不及只能焊接），上了 esp32+GPS+GPRS+心率+陀螺仪，硬件固件服务器前端演示动画一个人全包.jpg。接下来就是社会实践，去了甘肃省天水市齐寿中学支教，也爽快地飞了一把无人机，同时也当了一个莫的感情的书记员。采访了同学老师村民镇政府镇派出所酸菜厂老板市教育局市文旅局，还是感触良多。最后去了菲律宾长滩旅（咸）游（鱼）了五天，就才回来了。</p><p>最近呢算是加入了我们学校宋富老师的<a href="s3l.shanghaitech.edu.cn">系统与软件安全实验室（System and Software Security Laboratory, S3Lab）</a>，目前开始在做的课题是对 Facebook 新出的区块链 Libra 和 Move 语言的形式化验证，于是最近又忙着苦逼地读论文学 Rust。</p><p>下学期选了🥄🐟的概率论和宋富的编译原理，感觉又会是一个肝到爆炸的学期（（。现在甚至有点后悔大二上就选编译原理（汇编都没有系统地学过），但毕竟盘算着大三出国一年，还是要紧一点。</p><p>然后是有关一些坑。</p><p>第一个大概就是 hexo-leancloud-counter，当时也算是一腔热情被泼冷水，然后就心灰意冷.jpg。然后最近 Leancloud 发声明要求绑定备案域名才能提供服务，于是这个插件的门槛又进一步提高了，所以我想大概是名正言顺（？）地弃坑了叭。Leancloud 的确是一个比较棒的 BaaS 平台，当时还盘算着写点赞、投票、链接统计等功能，唉。不过遥遥无期地也还计划着用 Go 写一个通用的计数服务，到时候可能会开放一下 API。</p><p>然后是 Alanine，这个大概很少人知道叭，毕竟几乎没什么 progress。大概就是一个纯模块化的 headless CMS，当时选型一开始是 egg.js 然后切换到 nest.js，然而因为自己 Typescript 不够纯熟只能搁置。</p><p>然后是 meowthehoodie，一个游戏测评网站，域名已经买好了然而因为 Alanine 没有写出来所以啥都没有.jpg。</p><p>其实还有好多好多，课题组、社团、个人项目都还有一些没填的，只能慢慢来，一步走一步看了。</p><p>以及第二篇基石已经在写了，主题是 unicode 和 UTF-8，因为内容比较多所以这个暑假结束前写完放出来（赌上我的？？？一定不会咕）。</p><p>共勉。</p>]]></content>
    
    <summary type="html">
    
      &lt;center&gt;大家好，万年咕咕咕又回来了。&lt;/center&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>基石#1 | Base64 编码</title>
    <link href="https://leaferx.online/2019/04/10/cornerstone-1-base64/"/>
    <id>https://leaferx.online/2019/04/10/cornerstone-1-base64/</id>
    <published>2019-04-10T10:52:05.000Z</published>
    <updated>2019-04-10T10:52:05.960Z</updated>
    
    <content type="html"><![CDATA[<p>这是 Cornerstone 基石系列的第一篇，主题是 Base64 编码。</p><a id="more"></a><hr><h1 id="什么是-base64-编码"><a class="header-anchor" href="#什么是-base64-编码">¶</a>什么是 Base64 编码</h1><p>根据维基百科，字符编码（英语：Character encoding）、字集码是把字符集中的字符编码为指定集合中某一对象（例如：比特模式、自然数序列、8位组或者电脉冲），以便文本在计算机中存储和通过通信网络的传递<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>。</p><p>简而言之，编码就是使用一种数据格式来表达另一种数据格式的一个一一对应。</p><p>不过需要注意的是，Base64 编码中的“编码”二字并不符合上文中的字符编码的定义。恰恰相反，Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>。与 Base64 编码类似的二进制数据文本化方法还有 <a href="https://zh.wikipedia.org/wiki/Uuencode" rel="external nofollow noopener noreferrer" target="_blank">uuencode</a>、<a href="https://en.wikipedia.org/wiki/BinHex" rel="external nofollow noopener noreferrer" target="_blank">BinHex</a> 等。</p><p>由于 $64=2^6$，每个 Base64 编码字符可以表示 6 个比特（bit），而一个字节有 8 个比特（Byte），所以一个 Base64 编码字符可以表示 $\frac{3}{4}$ 个字节。由此我们可以知道，Base64 使用四个字节来编码三个字节，即被 Base64 编码过后的二进制数据会增大约 $\frac{4}{3}$ 倍。</p><p>用作 Base64 编码的字符集包括大写字母 <code>A-Z</code>、小写<code>a-z</code>，数字 <code>0-9</code>共 62 个，加上两个视不同 Base64 规范而不同的可打印字符（标准 Base64 规范使用的字符是 <code>+</code> 和 <code>/</code>）。</p><p>以下为 Base64 的索引表。</p><table><thead><tr><th style="text-align:center">数值</th><th style="text-align:center">字符</th><th style="text-align:center">数值</th><th style="text-align:center">字符</th><th style="text-align:center">数值</th><th style="text-align:center">字符</th><th style="text-align:center">数值</th><th style="text-align:center">字符</th></tr></thead><tbody><tr><td style="text-align:center">0</td><td style="text-align:center">A</td><td style="text-align:center">16</td><td style="text-align:center">Q</td><td style="text-align:center">32</td><td style="text-align:center">g</td><td style="text-align:center">48</td><td style="text-align:center">w</td></tr><tr><td style="text-align:center">1</td><td style="text-align:center">B</td><td style="text-align:center">17</td><td style="text-align:center">R</td><td style="text-align:center">33</td><td style="text-align:center">h</td><td style="text-align:center">49</td><td style="text-align:center">x</td></tr><tr><td style="text-align:center">2</td><td style="text-align:center">C</td><td style="text-align:center">18</td><td style="text-align:center">S</td><td style="text-align:center">34</td><td style="text-align:center">i</td><td style="text-align:center">50</td><td style="text-align:center">y</td></tr><tr><td style="text-align:center">3</td><td style="text-align:center">D</td><td style="text-align:center">19</td><td style="text-align:center">T</td><td style="text-align:center">35</td><td style="text-align:center">j</td><td style="text-align:center">51</td><td style="text-align:center">z</td></tr><tr><td style="text-align:center">4</td><td style="text-align:center">E</td><td style="text-align:center">20</td><td style="text-align:center">U</td><td style="text-align:center">36</td><td style="text-align:center">k</td><td style="text-align:center">52</td><td style="text-align:center">0</td></tr><tr><td style="text-align:center">5</td><td style="text-align:center">F</td><td style="text-align:center">21</td><td style="text-align:center">V</td><td style="text-align:center">37</td><td style="text-align:center">l</td><td style="text-align:center">53</td><td style="text-align:center">1</td></tr><tr><td style="text-align:center">6</td><td style="text-align:center">G</td><td style="text-align:center">22</td><td style="text-align:center">W</td><td style="text-align:center">38</td><td style="text-align:center">m</td><td style="text-align:center">54</td><td style="text-align:center">2</td></tr><tr><td style="text-align:center">7</td><td style="text-align:center">H</td><td style="text-align:center">23</td><td style="text-align:center">X</td><td style="text-align:center">39</td><td style="text-align:center">n</td><td style="text-align:center">55</td><td style="text-align:center">3</td></tr><tr><td style="text-align:center">8</td><td style="text-align:center">I</td><td style="text-align:center">24</td><td style="text-align:center">Y</td><td style="text-align:center">40</td><td style="text-align:center">o</td><td style="text-align:center">56</td><td style="text-align:center">4</td></tr><tr><td style="text-align:center">9</td><td style="text-align:center">J</td><td style="text-align:center">25</td><td style="text-align:center">Z</td><td style="text-align:center">41</td><td style="text-align:center">p</td><td style="text-align:center">57</td><td style="text-align:center">5</td></tr><tr><td style="text-align:center">10</td><td style="text-align:center">K</td><td style="text-align:center">26</td><td style="text-align:center">a</td><td style="text-align:center">42</td><td style="text-align:center">q</td><td style="text-align:center">58</td><td style="text-align:center">6</td></tr><tr><td style="text-align:center">11</td><td style="text-align:center">L</td><td style="text-align:center">27</td><td style="text-align:center">b</td><td style="text-align:center">43</td><td style="text-align:center">r</td><td style="text-align:center">59</td><td style="text-align:center">7</td></tr><tr><td style="text-align:center">12</td><td style="text-align:center">M</td><td style="text-align:center">28</td><td style="text-align:center">c</td><td style="text-align:center">44</td><td style="text-align:center">s</td><td style="text-align:center">60</td><td style="text-align:center">8</td></tr><tr><td style="text-align:center">13</td><td style="text-align:center">N</td><td style="text-align:center">29</td><td style="text-align:center">d</td><td style="text-align:center">45</td><td style="text-align:center">t</td><td style="text-align:center">61</td><td style="text-align:center">9</td></tr><tr><td style="text-align:center">14</td><td style="text-align:center">O</td><td style="text-align:center">30</td><td style="text-align:center">e</td><td style="text-align:center">46</td><td style="text-align:center">u</td><td style="text-align:center">62</td><td style="text-align:center">+<sup>*</sup></td></tr><tr><td style="text-align:center">15</td><td style="text-align:center">P</td><td style="text-align:center">31</td><td style="text-align:center">f</td><td style="text-align:center">47</td><td style="text-align:center">v</td><td style="text-align:center">63</td><td style="text-align:center">/<sup>*</sup></td></tr></tbody></table><p><em>padding: <code>=</code></em><br><em>* 视不同 Base64 标准而不同</em></p><h1 id="为什么我们需要-base64"><a class="header-anchor" href="#为什么我们需要-base64">¶</a>为什么我们需要 Base64</h1><p>在 <a href="https://zh.wikipedia.org/wiki/MIME" rel="external nofollow noopener noreferrer" target="_blank">MIME</a> 格式的电子邮件中，只能使用 ASCII 码的可打印字符。所以，人们需要发明一种编码方式，以 ASCII 可打印字符表示非 ASCII 码字符，以在邮件中嵌入图片、音频等二进制数据，也即 Base64 编码。事实上，Base64 编码是作为 MIME 多媒体电子邮件标准的一部分开发的<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>。</p><p>同时，在阮一峰老师的博客<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>中也提到 Base64 编码的其他意义：</p><ul><li>所有的二进制文件，都可以因此转化为可打印的文本编码，使用文本软件进行编辑；</li><li>能够对文本进行简单的加密。</li></ul><p>（尽管 Base64 作为一种简单的固定替换只能称作广义上的加密（与凯撒密码类似）。）</p><p>同时，Base64  编码可以用作在 URL 中传递二进制数据或非 URL-friendly 的数据，也可以用作以 <code>data: URL</code> 形式在 HTML 等文本文件中内嵌图片等二进制数据。当然，由于 <code>+</code> 和 <code>/</code> 是非 URL-friendly 的，我们需要使用一种用于 URL 的改进 Base64 编码（不在末尾填充 <code>=</code> 号，并将 <code>+</code> 和 <code>/</code> 替换为 <code>-</code> 和 <code>_</code>）<sup class="footnote-ref"><a href="#fn2" id="fnref2:1">[2]</a></sup>。</p><h1 id="base64-编码过程"><a class="header-anchor" href="#base64-编码过程">¶</a>Base64 编码过程</h1><p>将 3 字节的数据，先后放入一个 24 位的缓冲区中，先来的字节占高位。数据不足 3 字节的话，于缓冲器中剩下的比特用 0 补足。每次取出 6 比特，按照其值对应索引表中的字符作为编码后的输出，直到全部输入数据转换完成。</p><p>若原数据长度不是 3 的倍数时且剩下 1 个输入数据，则在编码结果后加 2 个<code>=</code>；若剩下 2 个输入数据，则在编码结果后加 1 个 <code>=</code><sup class="footnote-ref"><a href="#fn2" id="fnref2:2">[2]</a></sup>。</p><p>一个来自维基百科的例子：</p><style>  .center-table th, .center-table td {    text-align: center;  }  </style><table class="center-table">  <tbody>    <tr>      <th scope="row">文本</th>      <td colspan="8"><b>M</b></td>      <td colspan="8"><b>a</b></td>      <td colspan="8"><b>n</b></td>    </tr>    <tr>      <th scope="row">ASCII 编码</th><td colspan="8">77</td>      <td colspan="8">97</td>      <td colspan="8">110</td>    </tr>    <tr>      <th scope="row">二进制位</th>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>1</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>1</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>1</td>      <td>1</td>      <td>0</td>      <td>1</td>      <td>1</td>      <td>1</td>      <td>0</td>    </tr>    <tr>      <th scope="row">索引</th>      <td colspan="6">19</td>      <td colspan="6">22</td>      <td colspan="6">5</td>      <td colspan="6">46</td>    </tr>    <tr>      <th scope="row">Base64 编码</th>      <td colspan="6"><b>T</b></td>      <td colspan="6"><b>W</b></td>      <td colspan="6"><b>F</b></td>      <td colspan="6"><b>u</b></td>    </tr>  </tbody></table><p>另一个来自维基百科的例子（包含 padding <code>=</code>）：</p><table class="center-table">  <tbody>    <tr>      <th scope="row">文本（1 Byte）</th>      <td colspan="8"><b>A</b></td>      <td colspan="8"></td>      <td colspan="8"></td>    </tr>    <tr>      <th scope="row">二进制位</th>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>    </tr>    <tr>      <th scope="row">二进制位（补 0） </th>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td><b>0</b></td>      <td><b>0</b></td>      <td><b>0</b></td>      <td><b>0</b></td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>    </tr>    <tr>      <th scope="row">Base64 编码</th>      <td colspan="6"><b>Q</b></td>      <td colspan="6"><b>Q</b></td>      <td colspan="6">=</td>      <td colspan="6">=</td>    </tr>    <tr>      <th scope="row">文本（2 Byte）</th>      <td colspan="8"><b>B</b></td>      <td colspan="8"><b>C</b></td>      <td colspan="8"></td>    </tr>    <tr>      <th scope="row">二进制位</th>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>    </tr>    <tr>      <th scope="row">二进制位（补 0）</th>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>1</td>      <td>1</td>      <td><b>0</b></td>      <td><b>0</b></td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>      <td>0</td>    </tr>    <tr>      <th scope="row">Base64编码</th>      <td colspan="6"><b>Q</b></td>      <td colspan="6"><b>k</b></td>      <td colspan="6"><b>M</b></td>      <td colspan="6">=</td>    </tr>  </tbody></table><h1 id="用-javascript-实现-base64-编码与解码"><a class="header-anchor" href="#用-javascript-实现-base64-编码与解码">¶</a>用 JavaScript 实现 Base64 编码与解码</h1><p>目前主流的浏览器中都实现了全局方法 <code>atob()</code> 和 <code>btoa()</code>用于 Base64 的编码与解码。</p><p>因为 Base64 原理比较简单，我就顺便实现了一下，作为参考。因为只是随手的实现，没有仔细考虑效率和阅读他人代码，可能会有 bug，请不要用在实际用途中。</p><p>同时这份代码使用了 Node.js 中的 <code>Buffer</code>，这也将会是基石系列第二篇的主题。</p><p>要补充的一点是，在实际使用 Base64 时，<code>=</code> padding 可以视情况而省略，不影响数据的完整性（事实上，在这份代码的解码函数一开始就去掉了原数据的 padding）。具体原因很简单，这里略过不表，请读者自己思考。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">base64encode</span>(<span class="params">data, &#123;</span></span></span><br><span class="line"><span class="function"><span class="params">  char62 = <span class="string">'+'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">  char63 = <span class="string">'/'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">  padding = <span class="string">'='</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">&#125; = &#123;&#125;</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> c = Buffer.from(data);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> base64EncodeTab = <span class="string">`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789<span class="subst">$&#123;char62&#125;</span><span class="subst">$&#123;char63&#125;</span>`</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">let</span> str = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">Math</span>.ceil(c.byteLength / <span class="number">3</span>); i++) &#123;</span><br><span class="line">    <span class="keyword">const</span> p = <span class="number">3</span> * i;</span><br><span class="line">    str += base64EncodeTab[c[p] &gt;&gt; <span class="number">2</span>];</span><br><span class="line">    str += base64EncodeTab[((c[p] &lt;&lt; <span class="number">4</span>) &amp; <span class="number">0x3F</span>) | (c[p + <span class="number">1</span>] &gt;&gt; <span class="number">4</span>)];</span><br><span class="line">    <span class="keyword">const</span> remains = c.byteLength - p;</span><br><span class="line">    <span class="keyword">if</span> (remains === <span class="number">1</span>) <span class="keyword">break</span>;</span><br><span class="line">    str += base64EncodeTab[((c[p + <span class="number">1</span>] &lt;&lt; <span class="number">2</span>) &amp; <span class="number">0x3F</span>) | (c[p + <span class="number">2</span>] &gt;&gt; <span class="number">6</span>)];</span><br><span class="line">    <span class="keyword">if</span> (remains === <span class="number">2</span>) <span class="keyword">break</span>;</span><br><span class="line">    str += base64EncodeTab[c[p + <span class="number">2</span>] &amp; <span class="number">0x3F</span>];</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> str.padEnd(<span class="built_in">Math</span>.ceil(str.length / <span class="number">4</span>) * <span class="number">4</span>, padding);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">base64decode</span>(<span class="params">data, &#123;</span></span></span><br><span class="line"><span class="function"><span class="params">  char62 = <span class="string">'+'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">  char63 = <span class="string">'/'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">  padding = <span class="string">'='</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">  encoding = <span class="string">'utf-8'</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">&#125; = &#123;&#125;</span>) </span>&#123;</span><br><span class="line">  data = data.split(padding)[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> base64DecodeTab = <span class="function">(<span class="params">(chars</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">let</span> tmp = &#123;&#125;;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; chars.length; i++) tmp[chars[i]] = i; </span><br><span class="line">    <span class="keyword">return</span> tmp;</span><br><span class="line">  &#125;)(<span class="string">`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789<span class="subst">$&#123;char62&#125;</span><span class="subst">$&#123;char63&#125;</span>`</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> c = Buffer.alloc(<span class="built_in">Math</span>.ceil(data.length / <span class="number">4</span>) * <span class="number">3</span> + ((data.length + <span class="number">2</span>) % <span class="number">4</span>) - <span class="number">2</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">Math</span>.ceil(data.length / <span class="number">4</span>); i++) &#123;</span><br><span class="line">    <span class="keyword">const</span> p = <span class="number">4</span> * i;</span><br><span class="line">    c[<span class="number">3</span> * i] = (base64DecodeTab[data[p]] &lt;&lt; <span class="number">2</span>) | (base64DecodeTab[data[p + <span class="number">1</span>]] &gt;&gt; <span class="number">4</span>);</span><br><span class="line">    <span class="keyword">if</span> (p + <span class="number">2</span> &gt;= data.length) <span class="keyword">break</span>;</span><br><span class="line">    c[<span class="number">3</span> * i + <span class="number">1</span>] = ((base64DecodeTab[data[p + <span class="number">1</span>]] &lt;&lt; <span class="number">4</span>) &amp; <span class="number">0xFF</span>) | (base64DecodeTab[data[p + <span class="number">2</span>]] &gt;&gt; <span class="number">2</span>);</span><br><span class="line">    <span class="keyword">if</span> (p + <span class="number">3</span> &gt;= data.length) <span class="keyword">break</span>;</span><br><span class="line">    c[<span class="number">3</span> * i + <span class="number">2</span>] = ((base64DecodeTab[data[p + <span class="number">2</span>]] &lt;&lt; <span class="number">6</span>) &amp; <span class="number">0xFF</span>) | base64DecodeTab[data[p + <span class="number">3</span>]];</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> c.toString(encoding);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="base64-的不同标准"><a class="header-anchor" href="#base64-的不同标准">¶</a>Base64 的不同标准</h1><p>参见 <a href="https://en.wikipedia.org/wiki/Base64#Variants_summary_table" rel="external nofollow noopener noreferrer" target="_blank">维基百科（English only）</a> <sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>。</p><h1 id="base64-应用：data-urls"><a class="header-anchor" href="#base64-应用：data-urls">¶</a>Base64 应用：<code>Data URLs</code></h1><blockquote><p>Data URLs，即前缀为 <code>data:</code> 协议的 URL，其允许内容创建者向文档中嵌入小文件<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup>。</p></blockquote><p>Data URLs 的形式为：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">data:[&lt;mediatype&gt;][;base64],&lt;data&gt;</span><br></pre></td></tr></table></figure><p>其中，<code>&lt;mediatype&gt;</code> 为 MIME 类型的字符串，其默认值为 <code>text/plain;charset=US-ASCII</code> 。如果 <code>&lt;data&gt;</code> 为二进制类型，则需将其进行 Base64编码，并加上 <code>[;base64]</code> 选项。</p><p>具体的例子网上很多，这里就略过不表了。Data URLs 定义在 <a href="https://tools.ietf.org/html/rfc2397" rel="external nofollow noopener noreferrer" target="_blank">RFC 2397</a> <sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup>中，有兴趣的读者可以仔细阅读一下。</p><h1 id="base62x"><a class="header-anchor" href="#base62x">¶</a>Base62x</h1><blockquote><p>为了克服 Base64 由于输出内容中包括两个以上“符号类”字符（<code>+</code>、<code>/</code>、<code>=</code> 等）而带来的互不兼容多变种问题，一种输出内容无符号的 Base62x 编码方案被引入软件工程领域，Base62x 被视为无符号化的 Base64 改进版本。<sup class="footnote-ref"><a href="#fn2" id="fnref2:3">[2]</a></sup></p></blockquote><p><i><small>是国人提出的哦。</small></i></p><p>具体的 Base62x 描述可见 <a href="https://ieeexplore.ieee.org/document/6020065" rel="external nofollow noopener noreferrer" target="_blank">Base62x: An alternative approach to Base64 for non-alphanumeric characters</a><sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup>。</p><p>基本思路为，使用 <code>0-9</code>、<code>A-Z</code>、<code>a-w</code>、<code>x1</code>、<code>x2</code>、<code>x3</code>、<code>y</code>、<code>z</code> 作为编码集，并且省略 padding。其中 <code>x1</code>、<code>x2</code>、<code>x3</code> 被称为 tag，在解码过程中遇见字符 <code>x</code> 则与下一个字符共同解码。</p><p>使用 Base62x 编码的长度平均为原消息的 138%，区间为 $[\frac{4}{3},\frac{8}{3}]$，比 Base64 略大<sup class="footnote-ref"><a href="#fn8" id="fnref8:1">[8]</a></sup>。而在实际使用中，根据<a href="https://my.oschina.net/wadelau/blog/1591374" rel="external nofollow noopener noreferrer" target="_blank">这篇文章（来自 Base62x 作者）</a>，我们可以认为 Base62x 的编码效率比 Base64 略高<sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup>。</p><p>更多有关 Base62x 的资源以及其 Demo 可参见其<a href="https://ufqi.com/dev/base62x/" rel="external nofollow noopener noreferrer" target="_blank">官方网站</a><sup class="footnote-ref"><a href="#fn10" id="fnref10">[10]</a></sup>。</p><h1 id="utf-7"><a class="header-anchor" href="#utf-7">¶</a>UTF-7</h1><blockquote><p>由于在过去 SMTP 的传输仅能接受 7 比特的字符，而当时 Unicode 并无法直接满足既有的 SMTP 传输限制，在这样的背景下 UTF-7 被提出。严格来说 UTF-7 不能算是 Unicode 所定义的字符集之一，较精确的来说，UTF-7 是提供了一种将 Unicode 转换为 7 比特 US-ASCII 字符的转换方式<sup class="footnote-ref"><a href="#fn11" id="fnref11">[11]</a></sup>。</p></blockquote><p>详见<a href="https://zh.wikipedia.org/wiki/UTF-7" rel="external nofollow noopener noreferrer" target="_blank">维基百科</a><sup class="footnote-ref"><a href="#fn11" id="fnref11:1">[11]</a></sup>和 <a href="https://tools.ietf.org/html/rfc2152" rel="external nofollow noopener noreferrer" target="_blank">RFC 2152</a><sup class="footnote-ref"><a href="#fn12" id="fnref12">[12]</a></sup>。</p><h1 id="写在最后"><a class="header-anchor" href="#写在最后">¶</a>写在最后</h1><p>本来打算清明就写完的又咕咕咕了（笑</p><p>呼，终于写完了第一篇，虽然比之前计划的篇幅还是小了点（删了点比较复杂而且无关的细节，可以以后再单独写）。读了很多博客、wiki 和 RFC，学到了很多。再接再厉吧，我们下一篇见！</p><p>（马上就要考离散了咕咕咕咕咕咕</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p><a href="https://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81" rel="external nofollow noopener noreferrer" target="_blank">https://zh.wikipedia.org/wiki/字符编码</a> <a href="#fnref1" class="footnote-backref">↩</a></p></li><li id="fn2" class="footnote-item"><p><a href="https://zh.wikipedia.org/wiki/Base64" rel="external nofollow noopener noreferrer" target="_blank">https://zh.wikipedia.org/wiki/Base64</a> <a href="#fnref2" class="footnote-backref">↩</a> <a href="#fnref2:1" class="footnote-backref">↩</a> <a href="#fnref2:2" class="footnote-backref">↩</a> <a href="#fnref2:3" class="footnote-backref">↩</a></p></li><li id="fn3" class="footnote-item"><p><a href="https://segmentfault.com/a/1190000004533485" rel="external nofollow noopener noreferrer" target="_blank">https://segmentfault.com/a/1190000004533485</a> <a href="#fnref3" class="footnote-backref">↩</a></p></li><li id="fn4" class="footnote-item"><p><a href="http://www.ruanyifeng.com/blog/2008/06/base64.html" rel="external nofollow noopener noreferrer" target="_blank">http://www.ruanyifeng.com/blog/2008/06/base64.html</a> <a href="#fnref4" class="footnote-backref">↩</a></p></li><li id="fn5" class="footnote-item"><p><a href="https://en.wikipedia.org/wiki/Base64#Variants_summary_table" rel="external nofollow noopener noreferrer" target="_blank">https://en.wikipedia.org/wiki/Base64#Variants_summary_table</a> <a href="#fnref5" class="footnote-backref">↩</a></p></li><li id="fn6" class="footnote-item"><p><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/data_URIs" rel="external nofollow noopener noreferrer" target="_blank">https://developer.mozilla.org/zh-CN/docs/Web/HTTP/data_URIs</a> <a href="#fnref6" class="footnote-backref">↩</a></p></li><li id="fn7" class="footnote-item"><p><a href="https://tools.ietf.org/html/rfc2397" rel="external nofollow noopener noreferrer" target="_blank">https://tools.ietf.org/html/rfc2397</a> <a href="#fnref7" class="footnote-backref">↩</a></p></li><li id="fn8" class="footnote-item"><p><a href="https://ieeexplore.ieee.org/document/6020065" rel="external nofollow noopener noreferrer" target="_blank">https://ieeexplore.ieee.org/document/6020065</a> <a href="#fnref8" class="footnote-backref">↩</a> <a href="#fnref8:1" class="footnote-backref">↩</a></p></li><li id="fn9" class="footnote-item"><p><a href="https://my.oschina.net/wadelau/blog/1591374" rel="external nofollow noopener noreferrer" target="_blank">https://my.oschina.net/wadelau/blog/1591374</a> <a href="#fnref9" class="footnote-backref">↩</a></p></li><li id="fn10" class="footnote-item"><p><a href="https://ufqi.com/dev/base62x/" rel="external nofollow noopener noreferrer" target="_blank">https://ufqi.com/dev/base62x/</a> <a href="#fnref10" class="footnote-backref">↩</a></p></li><li id="fn11" class="footnote-item"><p><a href="https://zh.wikipedia.org/wiki/UTF-7" rel="external nofollow noopener noreferrer" target="_blank">https://zh.wikipedia.org/wiki/UTF-7</a> <a href="#fnref11" class="footnote-backref">↩</a> <a href="#fnref11:1" class="footnote-backref">↩</a></p></li><li id="fn12" class="footnote-item"><p><a href="https://tools.ietf.org/html/rfc2152" rel="external nofollow noopener noreferrer" target="_blank">https://tools.ietf.org/html/rfc2152</a> <a href="#fnref12" class="footnote-backref">↩</a></p></li></ol></section>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这是 Cornerstone 基石系列的第一篇，主题是 Base64 编码。&lt;/p&gt;
    
    </summary>
    
      <category term="Cornerstone 基石系列" scheme="https://leaferx.online/categories/Cornerstone-%E5%9F%BA%E7%9F%B3%E7%B3%BB%E5%88%97/"/>
    
    
      <category term="Node.js" scheme="https://leaferx.online/tags/Node-js/"/>
    
      <category term="JavaScript" scheme="https://leaferx.online/tags/JavaScript/"/>
    
      <category term="Conterstone" scheme="https://leaferx.online/tags/Conterstone/"/>
    
      <category term="基石" scheme="https://leaferx.online/tags/%E5%9F%BA%E7%9F%B3/"/>
    
      <category term="基础" scheme="https://leaferx.online/tags/%E5%9F%BA%E7%A1%80/"/>
    
      <category term="Fundamental" scheme="https://leaferx.online/tags/Fundamental/"/>
    
      <category term="Base64" scheme="https://leaferx.online/tags/Base64/"/>
    
      <category term="编码" scheme="https://leaferx.online/tags/%E7%BC%96%E7%A0%81/"/>
    
  </entry>
  
  <entry>
    <title>最近做的两件蠢事</title>
    <link href="https://leaferx.online/2019/04/03/two-stupid-things/"/>
    <id>https://leaferx.online/2019/04/03/two-stupid-things/</id>
    <published>2019-04-03T11:52:21.000Z</published>
    <updated>2019-04-03T13:01:29.439Z</updated>
    
    <content type="html"><![CDATA[<center>最近做了两件挺蠢的事情。</center><a id="more"></a><hr><p>第一件事呢，就是可能我太急躁了。在重构 LeanCloud Counter 的时候，步子迈的太大？然后可能由于语言不通或者什么，导致 NexT Team 有人认为我要篡权？</p><p>（#黑人问号.jpg？</p><p>也对，开源项目又没钱拿，xjb 重构吃力不讨好，没有新功能还容易被 diss（</p><p>不过就很莫名其妙 orz 还被开出了 NexT Team</p><p>（详情可以看<a href="https://github.com/theme-next/hexo-theme-next/pull/707" rel="external nofollow noopener noreferrer" target="_blank">这里</a></p><p>现在想想我也真是挺蠢的2333</p><hr><p>第二件事呢，就是真的我自己作死了。</p><p>在给自己的博客更新的时候，手滑 push 到了 master...</p><p>当我看到那个 100% 的时候，我内心就直接报警了。刚有点矛盾，还作死，这不是找死吗...</p><p>虽然并不会有什么影响，rebase 一下就好了。</p><p>然后就收获飞机票一张~</p><p>这件事告诉我，<code>git push</code> 的时候，一定要指定 remote。或者干脆，在 <code>git add remote</code> 的时候，直接把 push 和 fetch 的 url 设置成不一样的。的确，NexT 的 master 的 protection 不设置禁止直接 push 但设置其他限制导致 push 进去根本来不及后悔然而 rebase 或者 reset 的时候连 -f 都没用，像我这样的 careless junior git noob 根本不应该有 admin 权限（</p><p>果然还是我太菜了。</p><hr><p>好的其实，这篇文章是来宣传一下自己新写的 <a href="https://github.com/LEAFERx/hexo-leancloud-counter" rel="external nofollow noopener noreferrer" target="_blank">Hexo 插件</a>。全新重构的页面脚本，兼顾性能与扩展性；全新的极度友好的 <code>init</code> 命令，做到了完全自动化设置权限；改用 <code>master key</code> 作为鉴权方式，既安全又更加方便，同时也支持了 CI &amp; CD；同时，实时热门文章、实时点赞等功能也在计划当中。But, who really cares 呢？</p>]]></content>
    
    <summary type="html">
    
      &lt;center&gt;最近做了两件挺蠢的事情。&lt;/center&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>基石#0 | 开始之前的一些碎碎念</title>
    <link href="https://leaferx.online/2019/04/03/cornerstone-0/"/>
    <id>https://leaferx.online/2019/04/03/cornerstone-0/</id>
    <published>2019-04-03T11:51:32.000Z</published>
    <updated>2019-04-10T14:12:21.311Z</updated>
    
    <content type="html"><![CDATA[<p>这是 Cornerstone 基石系列的第零篇。</p><p>基石，如其名，在这个系列中，我将会写一些有关 JavaScript 和 Node.js 的基础、底层的一些东西。</p><p>为什么打算开始这个系列呢？其实我很早就有这个打算了。经常在 GitHub 上闲逛，读一些代码之类的，总感觉自己的基础还是不够扎实，对于很多代码和架构的理解，都只是浮于表面。同时，由于<a href="/2019/04/03/two-stupid-things/" title="一些原因">一些原因</a>，深刻地感受到了自己最近的心态可能过于浮躁，甚至于急功近利，所以希望自己能够沉淀一二。<em>“如果不写什么有意义的内容，光折腾博客、主题，这毫无意义。”</em></p><p>当然，好奇心也是一个很主要的原因。我发现，比起去学习如何使用 Vue，我更愿意从 Vue 是如何跑起来的下手，对于任何其他有趣的框架也是一样。然而以我目前的水平，还远远不能够理解他们的架构。贸然花费大量的时间去阅读源码，只是事倍功半。所以我打算从基础入手，潜心修炼（好中二哈哈哈）。</p><p>不过，由于学业繁忙（我真的是要忙死了 真实高四），我会尽量做到两周一篇的更新频率，也算是对自己的一种督促。</p><p>第零篇将会作为基石系列的目录和索引。</p><a id="more"></a><hr><p>基石#0 | 开始之前的一些碎碎念</p><a href="/2019/04/10/cornerstone-1-base64/" title="基石#1 | Base64 编码">基石#1 | Base64 编码</a><hr><p>好了最后再立点小目标吧。不仅是基础，自己的技术栈也需要扩大一点。目前打算学习的有 <code>TypeScript</code>、<code>Rxjs</code>、<code>Jest</code>，希望可以坚持。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这是 Cornerstone 基石系列的第零篇。&lt;/p&gt;
&lt;p&gt;基石，如其名，在这个系列中，我将会写一些有关 JavaScript 和 Node.js 的基础、底层的一些东西。&lt;/p&gt;
&lt;p&gt;为什么打算开始这个系列呢？其实我很早就有这个打算了。经常在 GitHub 上闲逛，读一些代码之类的，总感觉自己的基础还是不够扎实，对于很多代码和架构的理解，都只是浮于表面。同时，由于&lt;a href=&quot;/2019/04/03/two-stupid-things/&quot; title=&quot;一些原因&quot;&gt;一些原因&lt;/a&gt;，深刻地感受到了自己最近的心态可能过于浮躁，甚至于急功近利，所以希望自己能够沉淀一二。&lt;em&gt;“如果不写什么有意义的内容，光折腾博客、主题，这毫无意义。”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;当然，好奇心也是一个很主要的原因。我发现，比起去学习如何使用 Vue，我更愿意从 Vue 是如何跑起来的下手，对于任何其他有趣的框架也是一样。然而以我目前的水平，还远远不能够理解他们的架构。贸然花费大量的时间去阅读源码，只是事倍功半。所以我打算从基础入手，潜心修炼（好中二哈哈哈）。&lt;/p&gt;
&lt;p&gt;不过，由于学业繁忙（我真的是要忙死了 真实高四），我会尽量做到两周一篇的更新频率，也算是对自己的一种督促。&lt;/p&gt;
&lt;p&gt;第零篇将会作为基石系列的目录和索引。&lt;/p&gt;
    
    </summary>
    
      <category term="Cornerstone 基石系列" scheme="https://leaferx.online/categories/Cornerstone-%E5%9F%BA%E7%9F%B3%E7%B3%BB%E5%88%97/"/>
    
    
      <category term="Node.js" scheme="https://leaferx.online/tags/Node-js/"/>
    
      <category term="JavaScript" scheme="https://leaferx.online/tags/JavaScript/"/>
    
      <category term="Conterstone" scheme="https://leaferx.online/tags/Conterstone/"/>
    
      <category term="基石" scheme="https://leaferx.online/tags/%E5%9F%BA%E7%9F%B3/"/>
    
      <category term="基础" scheme="https://leaferx.online/tags/%E5%9F%BA%E7%A1%80/"/>
    
      <category term="Fundamental" scheme="https://leaferx.online/tags/Fundamental/"/>
    
  </entry>
  
  <entry>
    <title>让你的 Nginx 在配置文件改变时自动 reload</title>
    <link href="https://leaferx.online/2018/10/28/nginx-autoreload/"/>
    <id>https://leaferx.online/2018/10/28/nginx-autoreload/</id>
    <published>2018-10-28T10:05:14.000Z</published>
    <updated>2018-10-28T10:25:37.674Z</updated>
    
    <content type="html"><![CDATA[<p>最近在重新配置自己的服务器，搭建了 gitea + drones 做 CI/CD。自动部署 Nginx 的配置文件就是其中的一个目标。</p><p>因为我的 Nginx 是以 root 运行的，所以在 reload 的时候一定需要 sudo 权限，如果把 reload 放在 drones 的 CD 过程中，就必须要创建一个具有 nopasswd sudo 权限的账户，并且让 drones ssh 上这个账户运行 reload 命令。</p><p>这样做是十分不安全的，如果有人获得了修改我的配置文件 repo 的权限，或者做到了可以控制 drones，那么他也就自动获得了服务器的 nopassed sudo 权限。所以我决定把配置文件自动部署和 Nginx 自动重载分开，也就是由 root 运行一个 py 脚本监控配置文件夹，在配置文件改变时自动执行 <code>nginx -s reload</code> 命令。</p><a id="more"></a><hr><p>目前这份脚本已经上传至 GitHub：<a href="https://github.com/LEAFERx/nginx-autoreload-service" rel="external nofollow noopener noreferrer" target="_blank">nginx-autoreload-service</a></p><p>脚本使用了 <code>pyinotify</code> 来监视配置文件夹，并且写了一个 <code>.service</code> 文件交给 <code>systemd</code> 做后台守护。</p><p>脚本可以做到命令延时执行，也就是如果在一定时间修改了多份配置文件，延时过后 reload 命令只会执行一次。</p><p>安装及配置方法详见 GitHub README</p><hr><p>在写完这个脚本之后往 GitHub 一搜，就发现了很多类似的脚本，所以也权当练习了，而且那些脚本也不太符合我服务器的实际要求（尤其是延时执行，因为在 git pull 时可能会多次触发事件）。</p><p># EOF</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;最近在重新配置自己的服务器，搭建了 gitea + drones 做 CI/CD。自动部署 Nginx 的配置文件就是其中的一个目标。&lt;/p&gt;
&lt;p&gt;因为我的 Nginx 是以 root 运行的，所以在 reload 的时候一定需要 sudo 权限，如果把 reload 放在 drones 的 CD 过程中，就必须要创建一个具有 nopasswd sudo 权限的账户，并且让 drones ssh 上这个账户运行 reload 命令。&lt;/p&gt;
&lt;p&gt;这样做是十分不安全的，如果有人获得了修改我的配置文件 repo 的权限，或者做到了可以控制 drones，那么他也就自动获得了服务器的 nopassed sudo 权限。所以我决定把配置文件自动部署和 Nginx 自动重载分开，也就是由 root 运行一个 py 脚本监控配置文件夹，在配置文件改变时自动执行 &lt;code&gt;nginx -s reload&lt;/code&gt; 命令。&lt;/p&gt;
    
    </summary>
    
      <category term="后端" scheme="https://leaferx.online/categories/%E5%90%8E%E7%AB%AF/"/>
    
      <category term="Nginx" scheme="https://leaferx.online/categories/%E5%90%8E%E7%AB%AF/Nginx/"/>
    
    
      <category term="Nginx" scheme="https://leaferx.online/tags/Nginx/"/>
    
      <category term="Python" scheme="https://leaferx.online/tags/Python/"/>
    
      <category term="pyinotify" scheme="https://leaferx.online/tags/pyinotify/"/>
    
      <category term="systemd" scheme="https://leaferx.online/tags/systemd/"/>
    
  </entry>
  
  <entry>
    <title>OpenVZ + 强迫症 + Nginx Amplify</title>
    <link href="https://leaferx.online/2018/08/18/OpenVZLovesAmplify/"/>
    <id>https://leaferx.online/2018/08/18/OpenVZLovesAmplify/</id>
    <published>2018-08-18T15:23:02.000Z</published>
    <updated>2018-08-26T12:26:38.856Z</updated>
    
    <content type="html"><![CDATA[<p>OpenVZ ♥ Nginx Amplify !</p><p>如果你苦恼于 OpenVZ 架构的 VPS 使用 Nginx Amplify 一直有很多 <code>Metrics Unavailable</code>，这篇博客给出了解决方案。</p><a id="more"></a><h1 id="什么是-nginx-amplify"><a class="header-anchor" href="#什么是-nginx-amplify">¶</a>什么是 Nginx Amplify</h1><p>大概就是 Nginx 官方出品的一款 Nginx 和服务器系统的数据监控平台。</p><blockquote><p>NGINX Amplify is a SaaS‑based monitoring tool for the open source NGINX software and NGINX Plus. With NGINX Amplify you can monitor performance, keep track of infrastructure assets, and improve configuration with static analysis. NGINX Amplify also monitors the underlying OS, application servers (like PHP-FPM), databases, and other components. NGINX Amplify is simple to set up yet powerful enough to provide critical insight into NGINX and system performance.</p></blockquote><h1 id="安装-nginx-amplify-agent"><a class="header-anchor" href="#安装-nginx-amplify-agent">¶</a>安装 Nginx Amplify Agent</h1><p>首先前往 <a href="http://amplify.nginx.com" rel="external nofollow noopener noreferrer" target="_blank">amplify.nginx.com</a> 注册一个账户，然后按照提示一步一步键入指令安装 nginx-amplify-agent。</p><p>先下载安装脚本（用 curl 或者 wget）</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ curl -L -O https://github.com/nginxinc/nginx-amplify-agent/raw/master/packages/install.sh</span><br></pre></td></tr></table></figure><p>或者</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ wget https://github.com/nginxinc/nginx-amplify-agent/raw/master/packages/install.sh</span><br></pre></td></tr></table></figure><p>接着执行（需要 sudo 权限）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ API_KEY=<span class="string">'YOUR_API_KEY'</span> sh ./install.sh</span><br></pre></td></tr></table></figure><p>接着查看你的 Nginx 服务器是否带有 <code>http_stub_status_module</code> 模块。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo nginx -V 2&gt;&amp;1 | grep -o http_stub_status_module</span><br></pre></td></tr></table></figure><p>如果没有，则需要重新编译安装 Nginx 服务器。</p><p>然后在 <code>/etc/nginx/conf.d/</code> 下新建 <code>stub_status.conf</code> 文件，并粘贴入以下内容：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">127.0.0.1:80</span>;</span><br><span class="line">    <span class="attribute">server_name</span> <span class="number">127.0.0.1</span>;</span><br><span class="line">    <span class="attribute">location</span> /nginx_status &#123;</span><br><span class="line">        stub_status;</span><br><span class="line">        <span class="attribute">allow</span> <span class="number">127.0.0.1</span>;</span><br><span class="line">        <span class="attribute">deny</span> all;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>并重启 Nginx 服务器。</p><p>等一会儿后你的数据应该就会在 <a href="http://amplify.nginx.com" rel="external nofollow noopener noreferrer" target="_blank">amplify.nginx.com</a> 显示了。</p><h1 id="进一步配置-nginx-amplify-agent"><a class="header-anchor" href="#进一步配置-nginx-amplify-agent">¶</a>进一步配置 Nginx Amplify Agent</h1><p>参见 <a href="https://amplify.nginx.com/docs/guide-metrics-and-metadata.html#additional-nginx-metrics" rel="external nofollow noopener noreferrer" target="_blank">https://amplify.nginx.com/docs/guide-metrics-and-metadata.html#additional-nginx-metrics</a></p><p>具体呢就是在你的 Nginx 配置下，增加一个 log_format：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">log_format</span>  main_ext  <span class="string">'<span class="variable">$remote_addr</span> - <span class="variable">$remote_user</span> [<span class="variable">$time_local</span>] "<span class="variable">$request</span>" '</span></span><br><span class="line">                      <span class="string">'<span class="variable">$status</span> <span class="variable">$body_bytes_sent</span> "<span class="variable">$http_referer</span>" '</span></span><br><span class="line">                      <span class="string">'"<span class="variable">$http_user_agent</span>" "<span class="variable">$http_x_forwarded_for</span>" '</span></span><br><span class="line">                      <span class="string">'"<span class="variable">$host</span>" sn="<span class="variable">$server_name</span>" '</span></span><br><span class="line">                      <span class="string">'rt=<span class="variable">$request_time</span> '</span></span><br><span class="line">                      <span class="string">'ua="<span class="variable">$upstream_addr</span>" us="<span class="variable">$upstream_status</span>" '</span></span><br><span class="line">                      <span class="string">'ut="<span class="variable">$upstream_response_time</span>" ul="<span class="variable">$upstream_response_length</span>" '</span></span><br><span class="line">                      <span class="string">'cs=<span class="variable">$upstream_cache_status</span>'</span> ;</span><br></pre></td></tr></table></figure><p>然后将你的 access log 设为这个 format，并且把 error log 的等级设置为 warn。</p><p>最后重新加载 Nginx 配置就可以了。</p><h1 id="解决-nginx-http-errors-等-nginx-metrics-无法被收集的问题-干货-x1"><a class="header-anchor" href="#解决-nginx-http-errors-等-nginx-metrics-无法被收集的问题-干货-x1">¶</a>解决 NGINX HTTP Errors 等 NGINX Metrics 无法被收集的问题（干货 x1）</h1><p>如果配置完上一步之后，Amplify 网站中 NGINX HTTP Errors 等 Metrics 仍然显示 Metrics Unavailable，很大的可能性是因为你的 Nginx 服务器是以 root 身份运行的（至少我是这样）。然而 Amplify Agent 默认是以 Nginx 用户运行的，因为权限的原因，Amplify Agent 无法读到 Nginx 的日志。</p><p>首先看看 Amplify Agent 的运行日志（默认是 <code>/var/log/amplify-agent/agent.log</code> ）。如果看到类似 <code>supervisor failed to initialize pipeline for &quot;/var/log/nginx/access.log&quot; due to IOError (maybe has no rights?)</code> 的日志，那么就是上述的问题没跑了。</p><p>怎么解决呢？最自然的办法当然是让 Amplify Agent 以 root 运行。</p><h2 id="让-amplify-agent-以-root-运行"><a class="header-anchor" href="#让-amplify-agent-以-root-运行">¶</a>让 Amplify Agent 以 root 运行</h2><p>打开 Amplify Agent 的配置文件（默认是 <code>/etc/amplify-agent/agent.conf</code> ），修改 <code>[nginx]</code> 选项下的配置：</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[nginx]</span></span><br><span class="line"><span class="attr">user</span> = <span class="number">0</span></span><br></pre></td></tr></table></figure><p>然后重启 Amplify Agent 服务：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo service amplify-agent restart</span><br></pre></td></tr></table></figure><p>等几分钟后应该就可以看到 Nginx Metrics 都已经开始统计了。</p><p>不过，让程序以 root 运行可不是什么好习惯，有很大的安全隐患。有没有其他的方法呢？既然是 Amplify Agent 无法读到 root 用户的文件，那不妨让 Nginx 以非 root 运行，并且让 Nginx 和 Amplify Agent 处于同一用户之下，这样不就解决了吗。</p><p>这样的方法看上去很诱人，但坑却很多，而且做不到完美。至今我仍然找不到让 Amplify Agent 顺利收集 Nginx Disk I/O 的方法。</p><p><em>这里容我吐槽一下。 Nginx Disk I/O 未能被收集的原因是 Amplify Agent 没有对 <code>/proc/[pid]/io</code> 的读取权限，但是我看这个文件的拥有着明明是 nginx 而且权限是 <code>-r--------</code>，并且我把文件cp出去之后就能读取了.... 我深度怀疑是 SELinux 的锅，虽然我的服务器貌似并没有装 SELinux .... 经过各种怀疑人生之后，我还是决定以 root 运行 Amplify Agent，并且打算有空去折腾 docker &quot;nginx-with-amplify&quot; images。</em></p><h2 id="让-nginx-以非-root-运行"><a class="header-anchor" href="#让-nginx-以非-root-运行">¶</a>让 Nginx 以非 root 运行</h2><p>首先，建立一个账户，我这里就用 nginx 账户了。</p><p>然后，将 Nginx 的相关文件和目录都改为 nginx 账户所属。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo chown nginx /usr/sbin/nginx/</span><br><span class="line">$ sudo chown -R nginx /etc/nginx/</span><br><span class="line">$ sudo chown -R nginx /var/<span class="built_in">log</span>/nginx/</span><br></pre></td></tr></table></figure><p>从上到下依次是：Nginx 的可执行文件、Nginx 的配置目录、Nginx 的日志目录。</p><p>然后修改 Nginx 的配置：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">nginx.conf</span><br><span class="line"></span><br><span class="line"><span class="comment"># user = nginx;</span></span><br><span class="line"><span class="attribute">pid</span> /var/run/nginx/nginx.pid</span><br></pre></td></tr></table></figure><p>然后创建 Nginx 所需的 pid 文件所在的目录：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir /var/run/nginx</span><br><span class="line">$ sudo chown -R nginx /var/run/nginx/</span><br></pre></td></tr></table></figure><p>注意这里还要将其他与 Nginx 相关的文件和目录改变归属使得 Nginx 有权限访问。例如我的 https 证书存在 <code>/etc/letsencrypt/</code> 下，那就应该运行如下命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo chown -R nginx /etc/letsencrypt/</span><br></pre></td></tr></table></figure><p>Linux 系统对非 root 用户的限制是不能绑定 1024 以下的端口，所以我们还需要赋予 Nginx 绑定 80 和 443 端口的权限。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo nginx -s quit</span><br><span class="line">$ sudo <span class="built_in">setcap</span> CAP_NET_BIND_SERVICE=+eip /usr/sbin/nginx</span><br></pre></td></tr></table></figure><p>最后，以 nginx 用户身份启动 Nginx：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo -u nginx nginx</span><br></pre></td></tr></table></figure><p>这样 Nginx 和 Amplify Agent 就都以同一用户运行了，自然 Nginx 的相关信息也就可以被 Amplify Agent 所收集到了。</p><h1 id="解决-disk-i-o-等-system-metrics-无法被收集的问题-干货-x2"><a class="header-anchor" href="#解决-disk-i-o-等-system-metrics-无法被收集的问题-干货-x2">¶</a>解决 Disk I/O 等 System Metrics 无法被收集的问题（干货 x2）</h1><p>这个问题主要出在 psutil 模块对 OpenVZ 系统的不完全支持，目前我提交的修复性 Pull Request 已经被合并，而且新版本也已经发布，所以只要把 Amplify Agent 所使用的 psutil 模块替换成最新的版本就可以了。</p><p>找到 Amplify Agent 的程序包位置（我的是 <code>/usr/lib/python2.7/dist-packages/amplify</code>），把其下的 psutil 文件夹整个删除。然后用 pip 安装最新的 psutil：<code>pip install psutil</code>。</p><p>但是这样操作之后数据还是没有出来，我读了 Amplify 的源码发现 Amplify 不处理虚拟设备，也不会发送总 Disk 统计。然而 OpenVZ 的所有 Disk 一般都是虚拟设备，这也就导致没有任何有关 Disk 的数据被发送，所以我们还需要修改 <code>amplify/agent/collectors/system/metrics.py</code> 文件。</p><p>在 <code>disk_io_counters()</code> 函数定义下修改：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">146</span>         <span class="keyword">for</span> disk, io <span class="keyword">in</span> disk_counters.iteritems():</span><br><span class="line"><span class="number">147</span>                     <span class="comment"># do not process virtual devices</span></span><br><span class="line"><span class="number">148</span>                     disk_is_physical = <span class="keyword">False</span></span><br><span class="line"><span class="number">149</span>                     <span class="keyword">for</span> real_dev_name <span class="keyword">in</span> real_block_devs:</span><br><span class="line"><span class="number">150</span>                         <span class="keyword">if</span> disk.startswith(real_dev_name):</span><br><span class="line"><span class="number">151</span>                             disk_is_physical = <span class="keyword">True</span></span><br><span class="line"><span class="number">152</span>+</span><br><span class="line"><span class="number">153</span>+                    <span class="keyword">if</span> disk == <span class="string">'ploop14245'</span>: <span class="comment"># 这里改成你的块设备的名字（可以在 /sys/block/ 下查看）</span></span><br><span class="line"><span class="number">154</span>+                        disk_is_physical = <span class="keyword">True</span></span><br><span class="line"><span class="number">155</span>+</span><br></pre></td></tr></table></figure><p>修改之后重启 Amplify Agent：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo service amplify-agent restart</span><br></pre></td></tr></table></figure><p>稍等一会儿在 Nginx Amplify 页面上的 System 分页就可以看到 Disk I/O 等 Metrics 出现啦。</p><hr><h1 id="写在后面的话"><a class="header-anchor" href="#写在后面的话">¶</a>写在后面的话</h1><p>这次的捉虫子经历对于我一个 Linux 小白来说，真的是精疲力竭。尤其是我还在旅途中，大部分时间只能用着手机连上服务器的 SSH 进行调试和查看 log。</p><p>这次捉虫子也让我学到了很多吧。有点打算去看看 Linux 内核相关的东西了。</p><p>给你们看看当时我在空间里的吐槽orz：</p><blockquote><p>一开始我只是因为懒 想找个 nginx 图形化管理配置的面板<br>然后没找到但是看到了 amplify 一个可以分析配置的面板<br>然后果断安装但是一直有磁盘数据出不来<br>然后看官方文档说是权限问题 然后以 root 运行还是没用<br>然后去看源码 发现是psutil问题<br>然后去看 psutil 源码 发现是 openvz 架构不存在 /proc/diskstats<br>然后去服务商提工单 对面表示爱莫能助 要么加钱<br>然后去 psutil 提 issue 对面表示 pr is welcomed 也就是说希望你自己搞定并且贡献给开源社会<br>然后去查能不能伪造一个 /proc/diskstats 说在 /proc 下写文件需要写内核驱动<br>然后就开始研究 linux 内核驱动<br>…………………………<br>我真的一开始只是因为懒啊…</p></blockquote><hr><p>好啦这个长满荒草的博客或许终于又要开始更新啦。汇报一下最近可能的 bloggin 吧。最近正在肝一个 self-host 的评论系统 <a href="https://github.com/TryAlanine/Alanine" rel="external nofollow noopener noreferrer" target="_blank">Alanine</a>，采用了阿里的 eggjs 框架，因为实在找不到好用的评论系统，然后所以最近可能会写一点开发时踩的坑什么的。然后呢 SICP 系列或许可能真的应该要开始更新了吧。然后 NexT 这边的话，Leancloud Counter 还是有一大堆问题，半个月前重构了代码换用 REST API，但还是感觉配置过程太繁琐，不够优雅，所以最近可能会把插件重新写一遍，争取都能做到自动配置。</p><hr><p>顺便说一声，博客的评论因为没有提醒所以万年不看。微博私信知乎私信同理。如果有事找我，请邮箱。</p><hr><p>录了上科大，也马上 18 了。</p><p>安好。</p><hr><p>LEAFERx</p><p>2018年8月18日</p><p>写于赛里木湖畔，新疆</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;OpenVZ ♥ Nginx Amplify !&lt;/p&gt;
&lt;p&gt;如果你苦恼于 OpenVZ 架构的 VPS 使用 Nginx Amplify 一直有很多 &lt;code&gt;Metrics Unavailable&lt;/code&gt;，这篇博客给出了解决方案。&lt;/p&gt;
    
    </summary>
    
      <category term="后端" scheme="https://leaferx.online/categories/%E5%90%8E%E7%AB%AF/"/>
    
      <category term="Nginx" scheme="https://leaferx.online/categories/%E5%90%8E%E7%AB%AF/Nginx/"/>
    
    
      <category term="Nginx" scheme="https://leaferx.online/tags/Nginx/"/>
    
      <category term="Nginx Amplify" scheme="https://leaferx.online/tags/Nginx-Amplify/"/>
    
      <category term="OpenVZ" scheme="https://leaferx.online/tags/OpenVZ/"/>
    
  </entry>
  
  <entry>
    <title>[HEXO小技巧]在 hexo new 的时候自动用 VS Code 打开新建文章</title>
    <link href="https://leaferx.online/2018/03/17/hexo-auto-open-vscode/"/>
    <id>https://leaferx.online/2018/03/17/hexo-auto-open-vscode/</id>
    <published>2018-03-17T03:33:34.000Z</published>
    <updated>2018-03-17T08:45:41.927Z</updated>
    
    <content type="html"><![CDATA[<center>懒癌 hexo-blogger 的福音 / 吃我 Visual Studio Code 安利吔</center><a id="more"></a><hr><h1 id="安装-visual-studio-code"><a class="header-anchor" href="#安装-visual-studio-code">¶</a>安装 Visual Studio Code</h1><p>前往 <a href="https://code.visualstudio.com/" rel="external nofollow noopener noreferrer" target="_blank">Visual Studio Code 官网</a>下载最新版本的 VS Code 安装包，并在安装时勾选 <strong>添加到 PATH</strong> 。<br>同时，建议勾选其他三项（懒就要懒到底嘛qwq）。<br>如图所示：<img src="https://img.leaferx.ink/f7d11f5ae8dee71bd4f6.jpg" alt=""></p><h1 id="添加自动打开编辑器脚本"><a class="header-anchor" href="#添加自动打开编辑器脚本">¶</a>添加自动打开编辑器脚本</h1><p>在 <code>博客根目录/scripts/</code> 下新建 <code>AutoOpenEditor.js</code> 文件（取其他名字也可以，不影响）（如果没有 scripts 目录则新建），并粘贴以下代码，保存。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> spawn = <span class="built_in">require</span>(<span class="string">'hexo-util/lib/spawn'</span>);</span><br><span class="line"></span><br><span class="line">hexo.on(<span class="string">'new'</span>, (data) =&gt; &#123;</span><br><span class="line">  spawn(<span class="string">'code'</span>, [hexo.base_dir, data.path]);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>这样，在你每次 <code>hexo new</code> 的时候，脚本就会自动帮你打开 VS Code 并切换到博客根目录顺带打开新建的 .md 文件啦。<br>是不是又懒了一点呢qwq</p><hr><p>水这一篇就很开心qwq</p><p>PS：<a href="https://leaferx.online/2017/06/16/use-gulp-to-minimize/">利用 Gulp 来压缩你的 Hexo 博客</a>也更新了一种偷懒小技巧（在文末），还不快去看看？</p>]]></content>
    
    <summary type="html">
    
      &lt;center&gt;懒癌 hexo-blogger 的福音 / 吃我 Visual Studio Code 安利吔&lt;/center&gt;
    
    </summary>
    
      <category term="Hexo折腾" scheme="https://leaferx.online/categories/Hexo%E6%8A%98%E8%85%BE/"/>
    
    
      <category term="Hexo" scheme="https://leaferx.online/tags/Hexo/"/>
    
      <category term="博客" scheme="https://leaferx.online/tags/%E5%8D%9A%E5%AE%A2/"/>
    
      <category term="教程" scheme="https://leaferx.online/tags/%E6%95%99%E7%A8%8B/"/>
    
      <category term="技巧" scheme="https://leaferx.online/tags/%E6%8A%80%E5%B7%A7/"/>
    
  </entry>
  
  <entry>
    <title>A Guide to fix a security bug in Leancloud visitor counter</title>
    <link href="https://leaferx.online/2018/03/16/lc-security-en/"/>
    <id>https://leaferx.online/2018/03/16/lc-security-en/</id>
    <published>2018-03-16T04:25:33.000Z</published>
    <updated>2018-04-22T01:17:37.147Z</updated>
    
    <content type="html"><![CDATA[<p>The Leancloud visitor counter plugin used in NexT has a big security bug, by which someone could change your visitor number easily and even add/delete records in your database.</p><p>This bug is found by <a href="https://github.com/LEAFERx/" rel="external nofollow noopener noreferrer" target="_blank">LEAFERx</a> and confirmed by <a href="https://github.com/ivan-nginx" rel="external nofollow noopener noreferrer" target="_blank">Ivan.Nginx</a>.</p><ul><li><p>Related issue: <a href="https://github.com/theme-next/hexo-theme-next/issues/25" rel="external nofollow noopener noreferrer" target="_blank">#25</a></p></li><li><p>Related pr: <a href="https://github.com/theme-next/hexo-theme-next/pull/137" rel="external nofollow noopener noreferrer" target="_blank">#137</a></p></li><li><p>Related plugin: <a href="https://github.com/theme-next/hexo-leancloud-counter-security" rel="external nofollow noopener noreferrer" target="_blank">hexo-leancloud-counter-security</a></p></li></ul><p>This bug could only be fixed manually.</p><p><strong>Warning: All NexT sites using Leancloud visitor counter that are not fixed and other sites integrated this function by similiar ways are considered unsecurity. Please fix it as soon as possible.</strong></p><a id="more"></a><hr><p>Chinese version guide is <a href="https://leaferx.online/2018/02/11/lc-security/">here</a></p><hr><p>For convience, this doc also includes the way to setup the plugin. If you have already done this, skip to <em>Deploy web engine to avoid your data being changed illegally</em>.</p><p>Before you make the config, please upgrade your NexT version to v6.0.6 or greater.</p><p>Please note the difference between <strong>site config file</strong> and <strong>theme config file</strong></p><hr><h1 id="sign-up-to-leancloud-and-create-an-app"><a class="header-anchor" href="#sign-up-to-leancloud-and-create-an-app">¶</a>Sign up to Leancloud and create an app</h1><ul><li><p>Go to Leancloud website <a href="leancloud.cn">leancloud.cn</a> and sign up to Leancloud. Then login.</p></li><li><p>Click <code>1</code> to enter the console:</p><p><img src="https://img.leaferx.ink/fc0c048a1e25dc3d10aa.jpg" alt="1"></p></li><li><p>Then click <code>1</code> to create an app:</p><p><img src="https://img.leaferx.ink/33a56b754753a5d34b01.jpg" alt="2"></p></li><li><p>Type your app name in <code>1</code> in the pop up window(eg. &quot;test&quot;), then choose <code>2</code>, which means developer's plan, and then click <code>3</code> to create the app:</p><p><img src="https://img.leaferx.ink/649ccfc6f12015d1eefb.jpg" alt="3"></p></li></ul><h1 id="create-counter-class-and-enable-plugin-in-next"><a class="header-anchor" href="#create-counter-class-and-enable-plugin-in-next">¶</a>Create Counter class and enable plugin in NexT</h1><ul><li><p>Click <code>1</code>(app name) to enter the app manage page:</p><p><img src="https://img.leaferx.ink/d0889df29841661e0b9e.jpg" alt="4"></p></li><li><p>then click <code>1</code> to create a class for counter:</p><p><img src="https://img.leaferx.ink/b0fbc81bd6c19fa09a46.jpg" alt="5"></p></li><li><p>Type <code>Counter</code> in the pop up window in <code>1</code>, check <code>2</code>, then click <code>3</code>:</p><p><img src="https://img.leaferx.ink/ae6154d6a55f02f11ebf.jpg" alt="6"></p></li><li><p>Click <code>1</code> to enter the app setting, then click <code>2</code>:</p><p><img src="https://img.leaferx.ink/9501a6372918dd9a8a92.jpg" alt="8"></p></li><li><p>Paste <code>App ID</code> and <code>App Key</code> to <strong>theme config file</strong><code>_config.yml</code> like this:</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_visitors:</span></span><br><span class="line"><span class="attr">  enable:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;&gt;</span></span><br><span class="line">  <span class="comment"># Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security</span></span><br><span class="line"><span class="attr">  security:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  betterPerformance:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure></li><li><p>Set domain whitelist: Click<code>1</code>, then type your domain into <code>2</code>(<strong>protocol, domain and port should be exactly the same</strong>):</p></li></ul><p><img src="https://img.leaferx.ink/0e537cc4bec2e185201d.jpg" alt="9"></p><h1 id="deploy-web-engine-to-avoid-your-data-being-changed-illegally"><a class="header-anchor" href="#deploy-web-engine-to-avoid-your-data-being-changed-illegally">¶</a>Deploy web engine to avoid your data being changed illegally</h1><ul><li><p>Click <code>1 -&gt; 2 -&gt; 3</code> by order</p><p><img src="https://img.leaferx.ink/d7056dfeeef7c5d66318.jpg" alt="10"></p></li><li><p>Click<code>1</code>:</p><p><img src="https://img.leaferx.ink/2737841bbc2bdd572ae0.jpg" alt="11"></p></li><li><p>In the pop up window, click <code>1</code> to choose type <code>Hook</code>, then choose<code>beforeUpdate</code> in <code>2</code>, choose <code>Counter</code> in <code>3</code>. Paste code below into <code>4</code>, then click <code>5</code> to save it:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> query = <span class="keyword">new</span> AV.Query(<span class="string">"Counter"</span>);</span><br><span class="line"><span class="keyword">if</span> (request.object.updatedKeys.indexOf(<span class="string">'time'</span>) !== <span class="number">-1</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> query.get(request.object.id).then(<span class="function"><span class="keyword">function</span> (<span class="params">obj</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (obj.get(<span class="string">"time"</span>) + <span class="number">1</span> !== request.object.get(<span class="string">"time"</span>)) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> AV.Cloud.Error(<span class="string">'Invalid update!'</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img.leaferx.ink/a8e13418ed1d9405315b.jpg" alt="12"></p></li><li><p>Click <code>1</code> to deploy after the message in the red rect shows up:</p><p><img src="https://img.leaferx.ink/ca56bf2e5fc2a1343565.jpg" alt="13"></p></li><li><p>Click <code>1</code> in the pop up：</p><p><img src="https://img.leaferx.ink/17548c13b3b23c71d845.jpg" alt="14"></p></li><li><p>Click <code>1</code> to close the pop up window after the message in the red rect shows up:</p><p><img src="https://img.leaferx.ink/d2f50de6cefea9fd0ed3.jpg" alt="15"></p></li></ul><h1 id="set-access-control-for-your-database"><a class="header-anchor" href="#set-access-control-for-your-database">¶</a>Set access control for your database</h1><ul><li><p>Open <strong>theme config file</strong><code>_config.yml</code>, set <code>leancloud_visitors: security</code> to <code>true</code>:</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_visitors:</span></span><br><span class="line"><span class="attr">  enable:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;&gt;</span></span><br><span class="line">  <span class="comment"># Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security</span></span><br><span class="line"><span class="attr">  security:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  betterPerformance:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><p><strong>Explaination for <code>betterPerformance</code>:</strong><br>Because the Leancloud developer's plan has limits in requst thread amount and running time, counter number may be very slow to load in some times. If set <code>betterPerformance</code> to true, counter number will be displayed quickly by assuming the request is accepted normally.</p></li><li><p>Open cmd then switch to <strong>root path of site</strong>, type commands to install <code>hexo-leancloud-counter-security</code> plugin:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-leancloud-counter-security --save</span><br></pre></td></tr></table></figure></li><li><p>Open <strong>site config file</strong><code>_config.yml</code>, add those config:</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_counter_security:</span></span><br><span class="line"><span class="attr">  enable_sync:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;</span></span><br><span class="line"><span class="attr">  username:</span></span><br><span class="line"><span class="attr">  password:</span></span><br></pre></td></tr></table></figure></li><li><p>Type command:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo lc-counter register &lt;&lt;username&gt;&gt; &lt;&lt;password&gt;&gt;</span><br></pre></td></tr></table></figure><p>or</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo lc-counter r &lt;&lt;username&gt;&gt; &lt;&lt;password&gt;&gt;</span><br></pre></td></tr></table></figure><p>Change <code>&lt;&lt;username&gt;&gt;</code> and <code>&lt;&lt;password&gt;&gt;</code> to your own username and password (no need to be the same as leancloud account). They will be used in the hexo deploying.</p><ul><li>Open <strong>site config file</strong><code>_config.yml</code>, change <code>&lt;&lt;username&gt;&gt;</code> and <code>&lt;&lt;password&gt;&gt;</code>to those you set above:</li></ul><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_counter_security:</span></span><br><span class="line"><span class="attr">  enable_sync:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;</span></span><br><span class="line"><span class="attr">  username:</span> <span class="string">&lt;&lt;your</span> <span class="string">username&gt;&gt;</span> <span class="comment"># will be asked while deploying if be left blank</span></span><br><span class="line"><span class="attr">  password:</span> <span class="string">&lt;&lt;your</span> <span class="string">password&gt;&gt;</span> <span class="comment"># recommend to leave it blank for security, will be asked while deploying if be left blank</span></span><br></pre></td></tr></table></figure></li><li><p>Add the deployer in the <code>deploy</code> of <strong>site config file</strong><code>_config.yml</code>:</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="comment"># other deployer</span></span><br><span class="line"><span class="attr">  - type:</span> <span class="string">leancloud_counter_security_sync</span></span><br></pre></td></tr></table></figure></li><li><p>Return to the Leancloud console. Click <code>1 -&gt; 2</code>, check if there is a record added in the _User (the img below is using username &quot;admin&quot; for example):</p><p><img src="https://img.leaferx.ink/99faa5a0e7160e66d506.jpg" alt="16"></p></li><li><p>Click <code>1 -&gt; 2 -&gt; 3</code> by order:</p><p><img src="https://img.leaferx.ink/b72a9e64579f5b71749d.jpg" alt="17"></p></li><li><p><del>Click <code>1</code>(add_fields), then choose <code>2</code>:</del>Do as below &quot;create&quot; setting(choose the user you create):</p><p><img src="https://img.leaferx.ink/14a8cb37062693d768ad.jpg" alt="18"></p></li><li><p>click <code>1</code>(create), then choose <code>2</code>, type the username in <code>3</code>, then click <code>4 -&gt; 5</code>:</p><p><img src="https://img.leaferx.ink/d91714cfd703ef42b94c.jpg" alt="19"></p><p>Now your page should be similar to this img after finishing the step.</p><p><img src="https://img.leaferx.ink/c05e7ec9218820baf412.jpg" alt="20"></p></li><li><p>Click <code>1</code>(delete), then choose <code>2</code>:</p></li></ul><p><img src="https://img.leaferx.ink/c37b6e20726cfb1d3197.jpg" alt="21"></p><p>Now the bug is fixed.</p><p>Every time when you run <code>hexo d</code>, plugin will scan posts in the <code>source/_posts</code> and compare to the database, then add create records for those posts which are not list in the database. This procedure is done locally so that database can only be changed by you.</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;The Leancloud visitor counter plugin used in NexT has a big security bug, by which someone could change your visitor number easily and even add/delete records in your database.&lt;/p&gt;
&lt;p&gt;This bug is found by &lt;a href=&quot;https://github.com/LEAFERx/&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;LEAFERx&lt;/a&gt; and confirmed by &lt;a href=&quot;https://github.com/ivan-nginx&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Ivan.Nginx&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Related issue: &lt;a href=&quot;https://github.com/theme-next/hexo-theme-next/issues/25&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;#25&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Related pr: &lt;a href=&quot;https://github.com/theme-next/hexo-theme-next/pull/137&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;#137&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Related plugin: &lt;a href=&quot;https://github.com/theme-next/hexo-leancloud-counter-security&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;hexo-leancloud-counter-security&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This bug could only be fixed manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning: All NexT sites using Leancloud visitor counter that are not fixed and other sites integrated this function by similiar ways are considered unsecurity. Please fix it as soon as possible.&lt;/strong&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Hexo折腾" scheme="https://leaferx.online/categories/Hexo%E6%8A%98%E8%85%BE/"/>
    
    
      <category term="Hexo" scheme="https://leaferx.online/tags/Hexo/"/>
    
      <category term="博客" scheme="https://leaferx.online/tags/%E5%8D%9A%E5%AE%A2/"/>
    
      <category term="教程" scheme="https://leaferx.online/tags/%E6%95%99%E7%A8%8B/"/>
    
      <category term="NexT" scheme="https://leaferx.online/tags/NexT/"/>
    
      <category term="漏洞" scheme="https://leaferx.online/tags/%E6%BC%8F%E6%B4%9E/"/>
    
      <category term="Leancloud" scheme="https://leaferx.online/tags/Leancloud/"/>
    
  </entry>
  
  <entry>
    <title>由于GitHub放弃支持TLS1.0/1.1而导致的Hexo部署失败解决方法</title>
    <link href="https://leaferx.online/2018/02/26/hexo-deploy-error-becauseof-git-credential/"/>
    <id>https://leaferx.online/2018/02/26/hexo-deploy-error-becauseof-git-credential/</id>
    <published>2018-02-26T09:39:01.000Z</published>
    <updated>2018-03-28T10:31:47.834Z</updated>
    
    <content type="html"><![CDATA[<p>如果你最近在执行Hexo部署的时候遇到<code>fatal:HttpRequestException encountered</code>这个错误，这篇文章提供了解决方法。</p><a id="more"></a><h1 id="起因"><a class="header-anchor" href="#起因">¶</a>起因</h1><p>昨天因为一些情况修改了一点博文，在部署Hexo的时候发现出现了莫名其妙的错误，类似下图：<br><img src="https://img.leaferx.ink/b2305520feaebfc8b13c.jpg" alt=""><br>这个错误就很神奇，尤其是那个No error搞得我一脸懵逼...<br>尝试良久无果，于是改用ssh方式提交，成功。<br>与<a href="https://github.com/yrccondor" rel="external nofollow noopener noreferrer" target="_blank">@Axton</a>讨论过后，发现是gayhub最近停用了TLS1.0/1.1，然后巨硬底层太老不支持TLS1.2，于是https就提交不上去。<br><img src="https://img.leaferx.ink/706f25c065aece1e0041.jpg" alt=""><br>感谢<a href="https://github.com/yrccondor" rel="external nofollow noopener noreferrer" target="_blank">@Axton</a>供图2333</p><p>于是跑去hexo-deployer-git提<a href="https://github.com/hexojs/hexo-deployer-git/issues/102" rel="external nofollow noopener noreferrer" target="_blank">issue</a>，被告知问题已经被巨硬解决了，尝试了一下没有毛病。<br>不过我看目前仍很多人都还不知道解决方法，于是就打算写这么一篇短文。</p><h1 id="解决方法"><a class="header-anchor" href="#解决方法">¶</a>解决方法</h1><p>最为推荐的解决方法就是直接下载最新版（v2.16.2）的git，其中已经集成了巨硬提供的解决方法。<br><a href="https://git-scm.com/download/" rel="external nofollow noopener noreferrer" target="_blank">点我前往下载页面</a><br>如果你不愿意更新git，你也可以单独安装巨硬提供的解决方法：<br>在<a href="https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases/" rel="external nofollow noopener noreferrer" target="_blank">这个页面</a>下载最新版Git Credential Manager for Windows并安装。<br>完成安装后，问题就自动解决了。<br><strong>（安装完Git Credential Manager for Windows后请不要手贱卸载！！）</strong><br><strong>（不然重装后也一直是错误！！鬼知道这是什么原因...）</strong><br><strong>（然后下载了最新版git才解决问题）</strong></p><h1 id="相关issue"><a class="header-anchor" href="#相关issue">¶</a>相关issue</h1><p><a href="https://github.com/hexojs/hexo/issues/3043" rel="external nofollow noopener noreferrer" target="_blank">hexojs/hexo#3043</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;如果你最近在执行Hexo部署的时候遇到&lt;code&gt;fatal:HttpRequestException encountered&lt;/code&gt;这个错误，这篇文章提供了解决方法。&lt;/p&gt;
    
    </summary>
    
      <category term="Hexo折腾" scheme="https://leaferx.online/categories/Hexo%E6%8A%98%E8%85%BE/"/>
    
    
      <category term="Hexo" scheme="https://leaferx.online/tags/Hexo/"/>
    
      <category term="博客" scheme="https://leaferx.online/tags/%E5%8D%9A%E5%AE%A2/"/>
    
      <category term="教程" scheme="https://leaferx.online/tags/%E6%95%99%E7%A8%8B/"/>
    
      <category term="git" scheme="https://leaferx.online/tags/git/"/>
    
      <category term="前端" scheme="https://leaferx.online/tags/%E5%89%8D%E7%AB%AF/"/>
    
      <category term="bug修复" scheme="https://leaferx.online/tags/bug%E4%BF%AE%E5%A4%8D/"/>
    
  </entry>
  
  <entry>
    <title>Leancloud访客统计插件重大安全漏洞修复指南</title>
    <link href="https://leaferx.online/2018/02/11/lc-security/"/>
    <id>https://leaferx.online/2018/02/11/lc-security/</id>
    <published>2018-02-11T10:18:07.000Z</published>
    <updated>2018-04-22T01:15:51.711Z</updated>
    
    <content type="html"><![CDATA[<p><strong>2018.04.22：根据@huozk指出，文档在<a href="#wrong-place-20180422">此处</a>有错误，如果之前没有初始化过，则插件报错。现已修复。</strong></p><p>NexT主题使用的Leancloud访客统计插件存在重大安全漏洞，拥有不良企图的人利用该漏洞可随意更改访客数量或一定程度上增删数据库记录。<br>该漏洞由<a href="https://github.com/LEAFERx/" rel="external nofollow noopener noreferrer" target="_blank">我</a>独立发现，并由<a href="https://github.com/ivan-nginx" rel="external nofollow noopener noreferrer" target="_blank">Ivan.Nginx</a>确认。</p><ul><li>有关的issue：<a href="https://github.com/theme-next/hexo-theme-next/issues/25" rel="external nofollow noopener noreferrer" target="_blank">#25</a></li><li>有关的pr：<a href="https://github.com/theme-next/hexo-theme-next/pull/137" rel="external nofollow noopener noreferrer" target="_blank">#137</a></li><li>有关的插件：<a href="https://github.com/theme-next/hexo-leancloud-counter-security" rel="external nofollow noopener noreferrer" target="_blank">hexo-leancloud-counter-security</a></li></ul><p>经过讨论后，我们认为该漏洞必须由使用者手动修复。本文给出了修复方法。<br><strong>注意：所有使用该插件而未经修复的NexT站点或使用类似方法集成Leancloud访客统计功能的站点都被认为是不安全的，请尽快修复。</strong></p><p>For International Users:<br>This post is a guide to fix a serious security bug in Leancloud visitor counter, which is found by <a href="https://github.com/LEAFERx/" rel="external nofollow noopener noreferrer" target="_blank">me</a> and confirmed by <a href="https://github.com/ivan-nginx" rel="external nofollow noopener noreferrer" target="_blank">Ivan.Nginx</a>.<br>Someone could use this bug to change your visitor number easily and even add/delete records in your database.<br>This bug could only be fixed manually.</p><ul><li>related issue: <a href="https://github.com/theme-next/hexo-theme-next/issues/25" rel="external nofollow noopener noreferrer" target="_blank">#25</a></li><li>related pr: <a href="https://github.com/theme-next/hexo-theme-next/pull/137" rel="external nofollow noopener noreferrer" target="_blank">#137</a></li><li>related plugin: <a href="https://github.com/theme-next/hexo-leancloud-counter-security" rel="external nofollow noopener noreferrer" target="_blank">hexo-leancloud-counter-security</a></li></ul><p><strong>Warning: All NexT sites using Leancloud visitor counter that are not fixed and other sites integrated this function by similiar ways are considered unsecurity. Please fix it as soon as possible!</strong><br><del>English version guide is under translating and will be released in few days.</del><br><em>2018.3.16: English version guide is <a href="https://leaferx.online/2018/03/16/lc-security-en/">here</a></em></p><a id="more"></a><hr><p>为方便起见，本文将复述从头开始配置Leancloud访客统计插件的过程。<br>本文部分内容参考自Doublemine的<a href="https://notes.wanghao.work/2015-10-21-%E4%B8%BANexT%E4%B8%BB%E9%A2%98%E6%B7%BB%E5%8A%A0%E6%96%87%E7%AB%A0%E9%98%85%E8%AF%BB%E9%87%8F%E7%BB%9F%E8%AE%A1%E5%8A%9F%E8%83%BD.html#%E9%85%8D%E7%BD%AELeanCloud" rel="external nofollow noopener noreferrer" target="_blank">为NexT主题添加文章阅读量统计功能</a>。<br>对于已经完成该部分配置的用户，请自行对照本文步骤进行修复。</p><p><del>在配置前，请升级NexT至v6.0.5以上。<br><em>2018.2.26：目前NexTv6.0.5已经更新，但相关pr仍在讨论中。预计该漏洞将在v6.0.6修复</em><br><em>注：在本文发布时相关pull-request还在review当中，NexTv6.0.5仍未更新，请自行合并pr或按文末不更新主题的方法修复该漏洞。</em></del><br><em>2018.3.16：NexTv6.0.6已更新，该修复插件作为beta功能暂时添加，默认security选项为false，预计于v6.0.7正式添加。</em><br><em>2018.4.22：目前NexTv6.2.0已正式支持。</em></p><p>在配置过程中请注意<strong>博客配置文件</strong>和<strong>主题配置文件</strong>的区别。</p><hr><h1 id="注册leancloud并创建应用"><a class="header-anchor" href="#注册leancloud并创建应用">¶</a>注册Leancloud并创建应用</h1><ul><li>首先，前往Leancloud官网<a href="leancloud.cn">leancloud.cn</a>进行注册，并登陆。</li><li>然后点击图示<code>1</code>处，进入控制台：<img src="https://img.leaferx.ink/fc0c048a1e25dc3d10aa.jpg" alt="1"></li><li>接着，点击图示<code>1</code>处，创建应用：<img src="https://img.leaferx.ink/33a56b754753a5d34b01.jpg" alt="2"></li><li>在弹出窗口<code>1</code>处输入应用名称（可随意输入，可更改，为演示方便取名为test），并选择<code>2</code>处“开发版”，然后点击<code>3</code>处创建：<img src="https://img.leaferx.ink/649ccfc6f12015d1eefb.jpg" alt="3"></li></ul><p>到这里应用创建完成。</p><h1 id="建立counter类并在next中启用插件"><a class="header-anchor" href="#建立counter类并在next中启用插件">¶</a>建立Counter类并在NexT中启用插件</h1><ul><li>点击<code>1</code>处应用名称进入应用管理界面：<img src="https://img.leaferx.ink/d0889df29841661e0b9e.jpg" alt="4"></li><li>如图，点击侧边栏<code>1</code>处创建Class：<img src="https://img.leaferx.ink/b0fbc81bd6c19fa09a46.jpg" alt="5"></li><li>在弹出窗口<code>1</code>处填入<code>Counter</code>，勾选<code>2</code>处无限制，并点击<code>3</code>处创建Class：<img src="https://img.leaferx.ink/ae6154d6a55f02f11ebf.jpg" alt="6"></li><li>此时类已创建完成。接下来点击图示<code>1</code>处进入设置，然后点击<code>2</code>处进入应用Key：<img src="https://img.leaferx.ink/9501a6372918dd9a8a92.jpg" alt="8"></li><li>粘贴<code>App ID</code>和<code>App Key</code>到<strong>NexT主题配置文件</strong><code>_config.yml</code>对应位置。此时配置文件应如下：</li></ul><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_visitors:</span></span><br><span class="line"><span class="attr">  enable:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;&gt;</span></span><br></pre></td></tr></table></figure><ul><li>设置Web安全域名确保域名调用安全。点击<code>1</code>处进入安全中心，然后在<code>2</code>处填写自己博客对应的域名（<strong>注意协议、域名和端口号需严格一致</strong>）：<img src="https://img.leaferx.ink/0e537cc4bec2e185201d.jpg" alt="9"></li></ul><p>到这里内容均与Doublemine的<a href="https://notes.wanghao.work/2015-10-21-%E4%B8%BANexT%E4%B8%BB%E9%A2%98%E6%B7%BB%E5%8A%A0%E6%96%87%E7%AB%A0%E9%98%85%E8%AF%BB%E9%87%8F%E7%BB%9F%E8%AE%A1%E5%8A%9F%E8%83%BD.html#%E9%85%8D%E7%BD%AELeanCloud" rel="external nofollow noopener noreferrer" target="_blank">为NexT主题添加文章阅读量统计功能</a>这篇文章相同，只不过截图为新版的Leancloud的界面。</p><h1 id="部署云引擎以保证访客数量不被随意篡改"><a class="header-anchor" href="#部署云引擎以保证访客数量不被随意篡改">¶</a>部署云引擎以保证访客数量不被随意篡改</h1><ul><li>点击左侧<code>1</code>处云引擎，然后点击<code>2</code>处部署，再点击<code>3</code>处在线编辑：<img src="https://img.leaferx.ink/d7056dfeeef7c5d66318.jpg" alt="10"></li><li>点击<code>1</code>处创建函数：<img src="https://img.leaferx.ink/2737841bbc2bdd572ae0.jpg" alt="11"></li><li>在弹出窗口选择<code>1</code>处<code>Hook</code>类型，然后<code>2</code>处选择<code>beforeUpdate</code>，<code>3</code>处选择刚才建立的<code>Counter</code>类。在<code>4</code>中粘贴下方代码后，点<code>5</code>处保存。</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> query = <span class="keyword">new</span> AV.Query(<span class="string">"Counter"</span>);</span><br><span class="line"><span class="keyword">if</span> (request.object.updatedKeys.indexOf(<span class="string">'time'</span>) !== <span class="number">-1</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> query.get(request.object.id).then(<span class="function"><span class="keyword">function</span> (<span class="params">obj</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (obj.get(<span class="string">"time"</span>) + <span class="number">1</span> !== request.object.get(<span class="string">"time"</span>)) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> AV.Cloud.Error(<span class="string">'Invalid update!'</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如图所示：<img src="https://img.leaferx.ink/a8e13418ed1d9405315b.jpg" alt="12"></p><ul><li>点击保存后应出现类似红框处函数。此时点击<code>1</code>处部署：<img src="https://img.leaferx.ink/ca56bf2e5fc2a1343565.jpg" alt="13"></li><li>在弹出窗口点击<code>1</code>处部署：<img src="https://img.leaferx.ink/17548c13b3b23c71d845.jpg" alt="14"></li><li>等待出现红框处的成功部署信息后，点击<code>1</code>处关闭：<img src="https://img.leaferx.ink/d2f50de6cefea9fd0ed3.jpg" alt="15"></li></ul><p>至此云引擎已成功部署，任何非法的访客数量更改请求都将失败。</p><h1 id="进一步设置权限-可选-建议设置"><a class="header-anchor" href="#进一步设置权限-可选-建议设置">¶</a>进一步设置权限（可选，建议设置）</h1><ul><li>打开<strong>NexT主题配置文件</strong><code>_config.yml</code>，将leancloud_visitors下的security设置为true（如没有则新增）：</li></ul><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_visitors:</span></span><br><span class="line"><span class="attr">  enable:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;&gt;</span></span><br><span class="line">  <span class="comment"># Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security</span></span><br><span class="line"><span class="attr">  security:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  betterPerformance:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><p><strong>对<code>betterPerformance</code>选项的说明：</strong><br>由于Leancloud免费版的云引擎存在请求线程数和运行时间限制以及休眠机制，很多时候访客数量加载会很慢。如果设置<code>betterPerformance</code>为<code>true</code>，则网页则会在提交请求之前直接显示访客人数为查询到的人数+1，以增加用户体验。</p><ul><li>打开<strong>博客配置文件</strong><code>_config.yml</code>，新增以下配置：</li></ul><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_counter_security:</span></span><br><span class="line"><span class="attr">  enable_sync:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;</span></span><br><span class="line"><span class="attr">  username:</span> </span><br><span class="line"><span class="attr">  password:</span></span><br></pre></td></tr></table></figure><ul><li>打开cmd并切换至<strong>博客根目录</strong>，键入以下命令以安装<code>hexo-leancloud-counter-security</code>插件：</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-leancloud-counter-security --save</span><br></pre></td></tr></table></figure><ul><li><p>在相同目录键入以下命令：</p>  <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo lc-counter register &lt;&lt;username&gt;&gt; &lt;&lt;password&gt;&gt;</span><br></pre></td></tr></table></figure><p>或</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo lc-counter r &lt;&lt;username&gt;&gt; &lt;&lt;password&gt;&gt;</span><br></pre></td></tr></table></figure><p>将<code>&lt;&lt;username&gt;&gt;</code>和<code>&lt;&lt;password&gt;&gt;</code>替换为你自己的用户名和密码（不必与leancloud的账号）相同。此用户名和密码将在hexo部署时使用。</p></li><li><p>打开<strong>博客配置文件</strong><code>_config.yml</code>，将<code>&lt;&lt;username&gt;&gt;</code>和<code>&lt;&lt;password&gt;&gt;</code>替换为你刚刚设置的用户名和密码：</p></li></ul><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">leancloud_counter_security:</span></span><br><span class="line"><span class="attr">  enable_sync:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">  app_id:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">id&gt;&gt;</span></span><br><span class="line"><span class="attr">  app_key:</span> <span class="string">&lt;&lt;your</span> <span class="string">app</span> <span class="string">key&gt;</span></span><br><span class="line"><span class="attr">  username:</span> <span class="string">&lt;&lt;your</span> <span class="string">username&gt;&gt;</span> <span class="comment">#如留空则将在部署时询问</span></span><br><span class="line"><span class="attr">  password:</span> <span class="string">&lt;&lt;your</span> <span class="string">password&gt;&gt;</span> <span class="comment">#建议留空以保证安全性，如留空则将在部署时询问</span></span><br></pre></td></tr></table></figure><ul><li>在<strong>博客配置文件</strong><code>_config.yml</code>的<code>deploy</code>下添加项：</li></ul><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="comment"># other deployer</span></span><br><span class="line"><span class="attr">  - type:</span> <span class="string">leancloud_counter_security_sync</span></span><br></pre></td></tr></table></figure><ul><li>返回Leancloud控制台的应用内。依次点击<code>1</code> <code>2</code>，检查_User表中是否出现一条记录（图示以用户名为admin为例）：<img src="https://img.leaferx.ink/99faa5a0e7160e66d506.jpg" alt="16"></li><li>点击<code>1</code>处进入Counter表，依次点击<code>2</code> <code>3</code>，打开权限设置：<img src="https://img.leaferx.ink/b72a9e64579f5b71749d.jpg" alt="17"></li><li><span id="wrong-place-20180422"><del>点击<code>1</code>add_fields后选择<code>2</code>指定用户， 并将下两栏留空：</del></span>此处应与下条create设置相同（选择你所创建的用户）：<img src="https://img.leaferx.ink/14a8cb37062693d768ad.jpg" alt="18"></li><li>点击<code>1</code>create后选择<code>2</code>指定用户， 在<code>3</code>处键入用户名，点击<code>4</code>处后点击<code>5</code>处添加：<img src="https://img.leaferx.ink/d91714cfd703ef42b94c.jpg" alt="19">完成此步操作后，界面应与图示类似：<img src="https://img.leaferx.ink/c05e7ec9218820baf412.jpg" alt="20"></li><li>点击<code>1</code>delete后选择<code>2</code>指定用户， 并将下两栏留空：<img src="https://img.leaferx.ink/c37b6e20726cfb1d3197.jpg" alt="21"></li></ul><p>至此权限已设置完成，数据库记录只能在本地增删。<br>每次运行<code>hexo d</code>部署的时候，插件都会扫描本地<code>source/_posts</code>下的文章并与数据库对比，然后在数据库创建没有录入数据库的文章记录。<br>如果在<strong>博客配置文件</strong>中留空username或password，则在部署过程中程序会要求输入。</p><h1 id="del-手动修改lean-analytics-swig的方法-不建议-已过时-del"><a class="header-anchor" href="#del-手动修改lean-analytics-swig的方法-不建议-已过时-del">¶</a><del>手动修改lean-analytics-swig的方法（不建议）（已过时）</del></h1><p><del>不愿更新NexT主题的用户可使用此方法保证插件正常使用。<br><strong>强烈建议更新NexT至v6.0.5以上。</strong><br>打开<code>\layout\_third-party\analytics\lean-analytics.swig</code>文件，替换为以下内容：</del></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><span class="line">&#123;% if theme.leancloud_visitors.enable %&#125;</span><br><span class="line"></span><br><span class="line">  &#123;# custom analytics part create by xiamo; edited by LEAFERx #&#125;</span><br><span class="line">  &lt;script src=&quot;https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js&quot;&gt;&lt;/script&gt;</span><br><span class="line">  &lt;script&gt;AV.initialize(&quot;&#123;&#123;theme.leancloud_visitors.app_id&#125;&#125;&quot;, &quot;&#123;&#123;theme.leancloud_visitors.app_key&#125;&#125;&quot;);&lt;/script&gt;</span><br><span class="line">  &lt;script&gt;</span><br><span class="line">    function showTime(Counter) &#123;</span><br><span class="line">      var query = new AV.Query(Counter);</span><br><span class="line">      var entries = [];</span><br><span class="line">      var $visitors = $(&quot;.leancloud_visitors&quot;);</span><br><span class="line"></span><br><span class="line">      $visitors.each(function () &#123;</span><br><span class="line">        entries.push( $(this).attr(&quot;id&quot;).trim() );</span><br><span class="line">      &#125;);</span><br><span class="line"></span><br><span class="line">      query.containedIn(&apos;url&apos;, entries);</span><br><span class="line">      query.find()</span><br><span class="line">        .done(function (results) &#123;</span><br><span class="line">          var COUNT_CONTAINER_REF = &apos;.leancloud-visitors-count&apos;;</span><br><span class="line"></span><br><span class="line">          if (results.length === 0) &#123;</span><br><span class="line">            $visitors.find(COUNT_CONTAINER_REF).text(0);</span><br><span class="line">            return;</span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">          for (var i = 0; i &lt; results.length; i++) &#123;</span><br><span class="line">            var item = results[i];</span><br><span class="line">            var url = item.get(&apos;url&apos;);</span><br><span class="line">            var time = item.get(&apos;time&apos;);</span><br><span class="line">            var element = document.getElementById(url);</span><br><span class="line"></span><br><span class="line">            $(element).find(COUNT_CONTAINER_REF).text(time);</span><br><span class="line">          &#125;</span><br><span class="line">          for(var i = 0; i &lt; entries.length; i++) &#123;</span><br><span class="line">            var url = entries[i];</span><br><span class="line">            var element = document.getElementById(url);</span><br><span class="line">            var countSpan = $(element).find(COUNT_CONTAINER_REF);</span><br><span class="line">            if( countSpan.text() == &apos;&apos;) &#123;</span><br><span class="line">              countSpan.text(0);</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;)</span><br><span class="line">        .fail(function (object, error) &#123;</span><br><span class="line">          console.log(&quot;Error: &quot; + error.code + &quot; &quot; + error.message);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    function addCount(Counter) &#123;</span><br><span class="line">      var $visitors = $(&quot;.leancloud_visitors&quot;);</span><br><span class="line">      var url = $visitors.attr(&apos;id&apos;).trim();</span><br><span class="line">      var title = $visitors.attr(&apos;data-flag-title&apos;).trim();</span><br><span class="line">      var query = new AV.Query(Counter);</span><br><span class="line"></span><br><span class="line">      query.equalTo(&quot;url&quot;, url);</span><br><span class="line">      query.find(&#123;</span><br><span class="line">        success: function(results) &#123;</span><br><span class="line">          if (results.length &gt; 0) &#123;</span><br><span class="line">            var counter = results[0];</span><br><span class="line">            counter.fetchWhenSave(true);</span><br><span class="line">            counter.increment(&quot;time&quot;);</span><br><span class="line">            counter.save(null, &#123;</span><br><span class="line">              success: function(counter) &#123;</span><br><span class="line">                var $element = $(document.getElementById(url));</span><br><span class="line">                $element.find(&apos;.leancloud-visitors-count&apos;).text(counter.get(&apos;time&apos;));</span><br><span class="line">              &#125;,</span><br><span class="line">              error: function(counter, error) &#123;</span><br><span class="line">                console.log(&apos;Failed to save Visitor num, with error message: &apos; + error.message);</span><br><span class="line">              &#125;</span><br><span class="line">            &#125;);</span><br><span class="line">          &#125; else &#123;</span><br><span class="line">            &#123;% if theme.leancloud_visitors.security %&#125;</span><br><span class="line">              var $element = $(document.getElementById(url));</span><br><span class="line">              $element.find(&apos;.leancloud-visitors-count&apos;).text(&apos;Counter not initialized! See more at console err msg.&apos;);</span><br><span class="line">              console.error(&apos;ATTENTION! LeanCloud counter has security bug, for solve it see here: https://github.com/theme-next/hexo-leancloud-counter-security. \n If you see this message, you must have set the security config to true but not install the plugin.&apos;);</span><br><span class="line">            &#123;% else %&#125;</span><br><span class="line">              var newcounter = new Counter();</span><br><span class="line">              /* Set ACL */</span><br><span class="line">              var acl = new AV.ACL();</span><br><span class="line">              acl.setPublicReadAccess(true);</span><br><span class="line">              acl.setPublicWriteAccess(true);</span><br><span class="line">              newcounter.setACL(acl);</span><br><span class="line">              /* End Set ACL */</span><br><span class="line">              newcounter.set(&quot;title&quot;, title);</span><br><span class="line">              newcounter.set(&quot;url&quot;, url);</span><br><span class="line">              newcounter.set(&quot;time&quot;, 1);</span><br><span class="line">              newcounter.save(null, &#123;</span><br><span class="line">                success: function(newcounter) &#123;</span><br><span class="line">                  var $element = $(document.getElementById(url));</span><br><span class="line">                  $element.find(&apos;.leancloud-visitors-count&apos;).text(newcounter.get(&apos;time&apos;));</span><br><span class="line">                &#125;,</span><br><span class="line">                error: function(newcounter, error) &#123;</span><br><span class="line">                  console.log(&apos;Failed to create&apos;);</span><br><span class="line">                &#125;</span><br><span class="line">              &#125;);</span><br><span class="line">            &#123;% endif %&#125;</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        error: function(error) &#123;</span><br><span class="line">          console.log(&apos;Error:&apos; + error.code + &quot; &quot; + error.message);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    $(function() &#123;</span><br><span class="line">      var Counter = AV.Object.extend(&quot;Counter&quot;);</span><br><span class="line">      if ($(&apos;.leancloud_visitors&apos;).length == 1) &#123;</span><br><span class="line">        addCount(Counter);</span><br><span class="line">      &#125; else if ($(&apos;.post-title-link&apos;).length &gt; 1) &#123;</span><br><span class="line">        showTime(Counter);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">  &lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;strong&gt;2018.04.22：根据@huozk指出，文档在&lt;a href=&quot;#wrong-place-20180422&quot;&gt;此处&lt;/a&gt;有错误，如果之前没有初始化过，则插件报错。现已修复。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;NexT主题使用的Leancloud访客统计插件存在重大安全漏洞，拥有不良企图的人利用该漏洞可随意更改访客数量或一定程度上增删数据库记录。&lt;br&gt;
该漏洞由&lt;a href=&quot;https://github.com/LEAFERx/&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;我&lt;/a&gt;独立发现，并由&lt;a href=&quot;https://github.com/ivan-nginx&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Ivan.Nginx&lt;/a&gt;确认。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有关的issue：&lt;a href=&quot;https://github.com/theme-next/hexo-theme-next/issues/25&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;#25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;有关的pr：&lt;a href=&quot;https://github.com/theme-next/hexo-theme-next/pull/137&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;#137&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;有关的插件：&lt;a href=&quot;https://github.com/theme-next/hexo-leancloud-counter-security&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;hexo-leancloud-counter-security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;经过讨论后，我们认为该漏洞必须由使用者手动修复。本文给出了修复方法。&lt;br&gt;
&lt;strong&gt;注意：所有使用该插件而未经修复的NexT站点或使用类似方法集成Leancloud访客统计功能的站点都被认为是不安全的，请尽快修复。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For International Users:&lt;br&gt;
This post is a guide to fix a serious security bug in Leancloud visitor counter, which is found by &lt;a href=&quot;https://github.com/LEAFERx/&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;me&lt;/a&gt; and confirmed by &lt;a href=&quot;https://github.com/ivan-nginx&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Ivan.Nginx&lt;/a&gt;.&lt;br&gt;
Someone could use this bug to change your visitor number easily and even add/delete records in your database.&lt;br&gt;
This bug could only be fixed manually.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;related issue: &lt;a href=&quot;https://github.com/theme-next/hexo-theme-next/issues/25&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;#25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;related pr: &lt;a href=&quot;https://github.com/theme-next/hexo-theme-next/pull/137&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;#137&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;related plugin: &lt;a href=&quot;https://github.com/theme-next/hexo-leancloud-counter-security&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;hexo-leancloud-counter-security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Warning: All NexT sites using Leancloud visitor counter that are not fixed and other sites integrated this function by similiar ways are considered unsecurity. Please fix it as soon as possible!&lt;/strong&gt;&lt;br&gt;
&lt;del&gt;English version guide is under translating and will be released in few days.&lt;/del&gt;&lt;br&gt;
&lt;em&gt;2018.3.16: English version guide is &lt;a href=&quot;https://leaferx.online/2018/03/16/lc-security-en/&quot;&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Hexo折腾" scheme="https://leaferx.online/categories/Hexo%E6%8A%98%E8%85%BE/"/>
    
    
      <category term="Hexo" scheme="https://leaferx.online/tags/Hexo/"/>
    
      <category term="博客" scheme="https://leaferx.online/tags/%E5%8D%9A%E5%AE%A2/"/>
    
      <category term="教程" scheme="https://leaferx.online/tags/%E6%95%99%E7%A8%8B/"/>
    
      <category term="NexT" scheme="https://leaferx.online/tags/NexT/"/>
    
      <category term="漏洞" scheme="https://leaferx.online/tags/%E6%BC%8F%E6%B4%9E/"/>
    
      <category term="Leancloud" scheme="https://leaferx.online/tags/Leancloud/"/>
    
  </entry>
  
  <entry>
    <title>有关幻觉 有关和真实的纠葛</title>
    <link href="https://leaferx.online/2018/01/21/illusion-and-more/"/>
    <id>https://leaferx.online/2018/01/21/illusion-and-more/</id>
    <published>2018-01-21T03:53:19.000Z</published>
    <updated>2018-01-21T03:55:58.254Z</updated>
    
    <content type="html"><![CDATA[<blockquote class="blockquote-center"><p>我不是在谈论，我是在诘问。</p></blockquote><a id="more"></a><p>你记得你的床头柜上放有一束花。<br>清清楚楚，这束花在脑海中有画面。<br>可是你突然觉得不对，不知道为什么，就是，不对。<br>说不上来，一股难言的恐惧攫住了你。<br>摸索着起身，你向左偏头，没有。<br>没有。<br>哦，是梦。</p><p>还是现在才是梦。<br>花的每一分褶皱，每一条脉络，都不自觉地在你的脑海里呼啸。<br>你可以信誓旦旦。因为太真实。<br>一个被妄图挑战的问题：<br>究竟是“真实”在抗拒着真实，<br>还是真实在抗拒着“真实”？</p><p>类似的。<br>你如何判断，你正在看的这些文字，<br>太过真实而显得虚假。<br>你怎么知道你醒过来了。</p><p>究竟是真实，还是大脑的自动补全。<br>究竟什么是真实。<br>可触摸，可被感知，可被标准模型的拉格朗日量描述。<br>是吗？</p><p>缸中的大脑问题。<br>甚至是缸中的电脑问题。<br>你所运行的思想，是否被编程。<br>不是说被控制着，是被编程。<br>逻辑电路般，输入与输出的精准对应。<br>对你是黑盒，对缸外之人，内部过程可编程。<br>电解液才是灵魂。</p><p>伪随机数。</p><p>半夜惊醒时是最容易迷茫的时刻。<br>究竟是突然醒来，突然睡去，突然入梦，突然下一章。<br>还是早已确定好的cycle。<br>但我坚定地知道，盗梦空间中的陀螺，一定是虚假。</p><p>每个人都有自己的陀螺，籍此判断虚实。<br>往往是最后的倚仗。<br>或者说是防线吧。<br>然而其实只是不愿承认的心理安慰罢了。</p><p>陀螺是受控的。<br>重力控制陀螺，世界控制重力。<br>你控制世界，缸外的人控制你。<br>明白吗？</p><p>虚假的防线，可以轻易跨越的马奇诺。<br>奇怪的静坐战争。<br>静待亡国后再自由运动。</p><p>我不想在这里谈论，有关存在，有关所谓的物质性的、可受相互作用的真实。<br>我只是诘问，有关幻觉的纠葛。</p><p>往往，你会发现，你所倚仗的“真实”，总是充斥着象征性。<br>奇怪的仪式感，与应许之地之物链接。<br>但数据流究竟是单向还是双向，不得而知。</p><p>有时是对鲜血的渴望，是借生命力慰藉真实性。<br>有时是疼痛，从麻木的挤压中挣得半点呼吸的空间。</p><p>但是你在害怕，如果面向了错误的对象。<br>如果你倾注的是虚假，而将真实咀嚼。<br>如果。<br>如果你明白纠葛。<br>所以你在逃避开始。</p><p>空有全身愤懑而无可击之物。<br>气血逆行，叫你五内如焚。</p><p>我不是在谈论，我是在诘问。</p><p>希望你能彻底迷失于此。</p><p>一个夜里醒来的剑士和他的九十九里冰原。</p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote class=&quot;blockquote-center&quot;&gt;&lt;p&gt;我不是在谈论，我是在诘问。&lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>2018年1月站点更新</title>
    <link href="https://leaferx.online/2018/01/13/SiteUpdate201801/"/>
    <id>https://leaferx.online/2018/01/13/SiteUpdate201801/</id>
    <published>2018-01-13T08:31:55.000Z</published>
    <updated>2018-03-28T10:32:00.736Z</updated>
    
    <content type="html"><![CDATA[<p><img src="https://img.leaferx.ink/b64392485af74488de8a.jpg" alt=""></p><a id="more"></a><p>前一段时间因为沉迷彩虹六号全境封锁（划掉）（算了不划了），博客持续长草<br>然后最近终于想起来 就更新了一下主题（其实书单是一直一直在更新的qwqqq）<br>（其实主要是CloudFlare访问实在太慢了...就倒腾了一下LeanCloud把图片扔在上面 这样终于访问速度能忍受了）<br>大概等成年之后就去备个案 然后就能全站启用七牛CDN了 这样应该会快很多</p><p>嗷 所以这是一篇十分十分草率的文章<br>本来想写点近况的 可是懒qwq<br>那就假装《新年记杂》也算在内吧</p><p>那那那顺便加一下steam呀qwq id：LEAFERx<br>唯一的</p><h1 id="next主题已更新至6-0-1"><a class="header-anchor" href="#next主题已更新至6-0-1">¶</a>NexT主题已更新至6.0.1</h1><p>感谢Ivan.Nginx和其他人的贡献 目前NexT主题6.0.1版本已经正式放出<br>话说我的博客被挂在了README上了诶嘿嘿 还有名字也写在了contributor里<br>1w+stars的项目 赚翻了赚翻了</p><h2 id="图片和js库等部分静态资源临时托管至leancloud和staticfile-org上"><a class="header-anchor" href="#图片和js库等部分静态资源临时托管至leancloud和staticfile-org上">¶</a>图片和js库等部分静态资源临时托管至LeanCloud和staticfile.org上</h2><p>为什么说临时是因为现在LeanCloud上文件都是手动上传粘贴链接的，十分不方便，以后肯定要换<br>本来打算用七牛CDN的，可是要备案，那就只能等到成年了orz</p><h2 id="加入pace-js页面加载进度条"><a class="header-anchor" href="#加入pace-js页面加载进度条">¶</a>加入Pace.js页面加载进度条</h2><p>从现在开始页面加载就有进度条动画了，不会就卡在哪里，用户体验大概会好很多吧</p><h2 id="加入站点和文章字数统计"><a class="header-anchor" href="#加入站点和文章字数统计">¶</a>加入站点和文章字数统计</h2><p>虽然这个插件连代码字数都统计了进去造成一种写了很多字的错觉，但是看起来爽啊qwq</p><h2 id="其他细节性修改"><a class="header-anchor" href="#其他细节性修改">¶</a>其他细节性修改</h2><p>还有些啥呢emmmm记不得了<br>那就假装有点细节上的修改好了</p><hr><p>好 这篇草率的文章就让它结束吧<br>另外 1336大概最近会更新一下<br>可以去看看 也欢迎投稿w<br>qq上或者邮箱上找我就好</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;https://img.leaferx.ink/b64392485af74488de8a.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="博客通知" scheme="https://leaferx.online/categories/%E5%8D%9A%E5%AE%A2%E9%80%9A%E7%9F%A5/"/>
    
      <category term="更新" scheme="https://leaferx.online/categories/%E5%8D%9A%E5%AE%A2%E9%80%9A%E7%9F%A5/%E6%9B%B4%E6%96%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>新年记杂</title>
    <link href="https://leaferx.online/2018/01/11/write-for-2018/"/>
    <id>https://leaferx.online/2018/01/11/write-for-2018/</id>
    <published>2018-01-11T09:28:49.000Z</published>
    <updated>2018-03-28T10:32:00.307Z</updated>
    
    <content type="html"><![CDATA[<p><img src="https://img.leaferx.ink/4a2dd9d5b039a3a8425c.jpg" alt="">本文于2018年1月1日首发于公众号<a href="https://mp.weixin.qq.com/s?__biz=MzUxNTEyMDUyMA==&amp;mid=2247483778&amp;idx=2&amp;sn=067b7dbb72d975e0b749884b20534446&amp;chksm=f9bacd65cecd4473a833b8cba9363ac4e5a0c1110618efade3f83197af78c75458d47e9fd8d7&amp;mpshare=1&amp;scene=23&amp;srcid=0111NxDnaaWnYm2HgZKp0xQO#rd" rel="external nofollow noopener noreferrer" target="_blank">Y92170号星星</a><br>号的主人是一位很厉（la）害（ji）的小姐姐 欢迎大家关注qwq<br>本来不打算发在这里的 毕竟是技术博客嘛<br>但是......随便了qwq说不定有<strong>打赏</strong>呢</p><a id="more"></a><hr><p>记得写过一篇平安夜记杂，尽是些不成文的语句。<br>回忆跌跌撞撞破门而入。五年。<br>五年，数以千记的日子，多少个五年。</p><p>又是一年元旦，扳扳手指，也已经数不过来了。<br>乱，实在是乱。乱到很多回忆自动被揉进幻觉，还是幻觉里面掺杂着一点回忆。<br>不知道，不知道。楼去而人空。</p><p>2017，with chaos an’ anxiety。<br>恍恍惚惚地，恍恍惚惚地，晃过去了。<br>留下了多少？问自己。<br>不知道，不知道。茶走而人凉。<br>大脑在嗡嗡作响，是机械硬盘的声音。<br>是自动地在删除些什么，又是自动地在插入着什么。<br>不知道，不知道。只有脚本才知道。</p><p>在写什么，不知道，迷茫，反正是记杂，那就杂。<br>那就先摸摸看到这里的你吧w<br>那也请你暂且放一下，看看今天的月亮。<br>请你含情脉脉地看看她，然后告诉我圆不圆，好吗？<br>这很重要。</p><p>在你看月亮的时候，让我偷偷地溜走一段吧。<br>我对月亮这个意象总是情有独钟。<br>不知道，不知道。矛盾的美。<br>鲁迅的“直刺着天空中圆满的月亮，使月亮窘得发白。”<br>她窘得发白，我爱她，因为她的另一面是深沉的黑。</p><p>回来了吧，告诉我，圆不圆。这很重要。<br>我的膝盖上枕着八斤重的电脑，好疼。<br>我在等你回话。</p><p>让我们来谈一点严肃的吧。</p><p>生而为人，真是对不起呀。<br>生活对于那些想要前行的人，真是太太太太刻薄了。<br>不是吗？你只要停下，她也会停下。<br>月亮跟着你走，月亮一样。<br>但你不能停下呀。停下了，就<br>就真的停下了。</p><p>但是呀。<br>但是。但是。<br>还有六七十年七八十年好活。<br>不是吗？那就把其中的几年送给生活当作谢礼。<br>谢谢她的刻薄，尽管你不想要。</p><p>鸡汤，对吗。<br>也是。你为什么就这么不屑呢。<br>你有什么资格，可以看到这里呢。<br>你是谁呢。</p><p>哈，开玩笑的啦。<br>你还没有回答我<br>月亮<br>到底<br>圆不圆呀。</p><p>啊不行。电脑好重。<br>让我趴着写一会儿。</p><p>那就说点甜的吧。</p><p>“包产到户”<br>真好呀。别人家的。</p><p>呐。如果你可以忍受的了我的混乱。<br>读到了这里。我想对你说。<br>对，就是对你说，不要往后看啦。<br>对你说：<br>喜欢你，绝非一言一语，一朝一夕。<br>喜欢你，就想让所有的，所有的雨都落向你。<br>喜欢你，想让樱花，让粉红色在你身上燃起。<br>喜欢你，让氢原子被自由电子捉去。</p><p>但你喜欢空虚中的暗夜啊，鲁迅所说的，盾牌后的空虚中的暗夜。<br>所以，所以所以<br>啊，趴着好难受，让我起来缓一缓。</p><p>呐，薛定谔被我的猫挠死啦。<br>“正是子夜时分。雨水敲打着窗户。不是子夜。没有下雨。”<br>来自塞缪尔·贝克特的《莫洛伊》。<br>嘿，我要把它送给你。</p><p>甜的说完啦，让我们继续混乱一点。<br>最近的一个月，过得十分十分文科生。<br>《古代汉语常识》《鲁迅选集》《文学阅读指南》《诗的八堂课》<br>你知道吗，在古代，“睡觉”解作“睡醒”<br>所以很晚啦，快去睡觉，晚安。</p><p>w</p><p>好的嘛，知道你不想睡。<br>那么，人为什么而活呢？<br>你知道吗。<br>告诉我好吗。<br>这也很重要。<br>不过还是月亮圆不圆更重要一点。<br>置死地而后生，<br>至死地而后不生吧。<br>月亮噎住了我，喝一杯黑夜润润喉。</p><p>吾辈皆如蚁。<br>仅为美如神。<br>顾城，顾城。</p><p>可是大火来了。会夺走一切的大火来了。<br>滚滚黑烟中，数不尽的幻觉肆意掠夺。<br>麻木而又冰冷，僵硬和悲伤在攻城掠地。</p><p>或许每一个人都有这样的念头：<br>为什么不是我？</p><p>对吗。</p><p>好，戛然而止吧。</p><p>被2017的末尾杀死的你。<br>2018，新年，我要祝你不快乐。</p><p>傻子，月亮圆吗？<br>新年快乐呀。</p><p>别管2017了。<br>2018快乐。<br>别管2018会不会快乐。<br>先快乐再说。</p><p>困顿、不自知<br>一个活着的人作于年末的夜空中</p><hr><p>另附上一些不成文的词句<br>望不要嫌弃</p><p>云淡风轻还是波澜不惊<br>活还是死<br>淡漠 淡漠 没有仙人掌的沙漠<br>转瞬即逝的<br>回忆都会被雕刻<br>而幻觉总是自动闯入<br>流淌着的灵魂 太沉<br>伯努利方程<br>守恒 却总是熵增<br>活着就是氧化<br>混乱 混乱 分子被拆散<br>消散 消散<br>缸中大脑 怕不是缸中电脑<br>信息 信息 外界刺激<br>内部过程可编程<br>电解液才是灵魂<br>Do androids dream of electric sheep？<br>从灰色爬上黑色<br>还是从黑色掉入灰暗<br>那就割掉自己的左耳吧<br>剪断反馈的路线 剪断闭环<br>一劈两半<br>莫比乌斯环<br>然后掩埋<br>掩埋<br>庞贝和锡安<br>宇宙终将变成沙滩</p><hr><p>最后的最后<br>衷心地祝愿胡太伟老师新年快乐<br>愿天堂再无病痛</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;https://img.leaferx.ink/4a2dd9d5b039a3a8425c.jpg&quot; alt=&quot;&quot;&gt;本文于2018年1月1日首发于公众号&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=MzUxNTEyMDUyMA==&amp;amp;mid=2247483778&amp;amp;idx=2&amp;amp;sn=067b7dbb72d975e0b749884b20534446&amp;amp;chksm=f9bacd65cecd4473a833b8cba9363ac4e5a0c1110618efade3f83197af78c75458d47e9fd8d7&amp;amp;mpshare=1&amp;amp;scene=23&amp;amp;srcid=0111NxDnaaWnYm2HgZKp0xQO#rd&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Y92170号星星&lt;/a&gt;&lt;br&gt;
号的主人是一位很厉（la）害（ji）的小姐姐 欢迎大家关注qwq&lt;br&gt;
本来不打算发在这里的 毕竟是技术博客嘛&lt;br&gt;
但是......随便了qwq说不定有&lt;strong&gt;打赏&lt;/strong&gt;呢&lt;/p&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>2017年6月全站重大更新</title>
    <link href="https://leaferx.online/2017/06/17/SiteUpdate201706/"/>
    <id>https://leaferx.online/2017/06/17/SiteUpdate201706/</id>
    <published>2017-06-17T02:10:45.000Z</published>
    <updated>2018-03-28T10:31:57.859Z</updated>
    
    <content type="html"><![CDATA[<p><img src="https://img.leaferx.ink/0ea297aaa2ff47b004e7.jpg" alt=""></p><a id="more"></a><h1 id="新域名leaferx-online已投入使用"><a class="header-anchor" href="#新域名leaferx-online已投入使用">¶</a>新域名leaferx.online已投入使用</h1><p>手一抖就花了5块钱买了个新域名orz 不过至少比leaferx.github.io好一点qwq<br>github不能挂SSL证书是真的麻烦 最后只能用CloudFlare来反代一下<br>CloudFlare是真的良心 不仅搞定了SSL而且能自动续期（虽然是公用SSL证书） 还有CDN加成（虽然都是美国节点）和安防（虽然对Github Pages并没有什么卵用） 甚至还可以做到全站http直接301到https 以及增加了网站统计功能 简直Github Pages最佳伴侣 最重要是的这些还都免费 所以忍不住打个广告qwq</p><p>不过对墙内的朋友们就不太友好了...Github和CloudFlare各种被半墙...有时间得弄下国内CDN<br>换了域名百度那边瞬间爆炸 本就不多的索引量瞬间清零 不过最近并没有什么SEO的想法<br>而且百度站长这个工具实在太难用了 各种通不过验证 简直毒 于是更没有兴趣了</p><p>由于全站访客人数统计用的是不蒜子 所以更换域名后4000+的人数被清零了 要重新开始<br>所以请大家来后多刷新几下再走啊qwqqqqqqqqqqqq</p><p><img src="https://img.leaferx.ink/6b5992490d4ad5ed0f01.jpg" alt=""><br><img src="https://img.leaferx.ink/726130e60ca11bd7446d.jpg" alt=""></p><h1 id="评论系统已更换为livere"><a class="header-anchor" href="#评论系统已更换为livere">¶</a>评论系统已更换为LiveRe</h1><p><img src="https://img.leaferx.ink/39134ddfc6d03a6ecb60.jpg" alt=""><br>今年多说停止服务了 这么好的一个社会化评论系统彻底归为历史<br>于是一直在找多说的代替品<br>然而Disqus被墙 网易云更贴和搜狐畅言实在太丑...<br>前段时间一直在用Gitment过渡 为此我还发了个PR<br>Gitment好是好 但是只支持Github账户 面向群体有些小众 而且在移动端貌似还有奇奇怪怪的问题 于是还是琢磨着要换一个<br>然后在看到livere的时候就立刻拍板 就是它了（虽然中文名来必力真的很蠢而且总是让我想起来必堡......）<br>支持Github、QQ、微信登录 所以少年不如评论一发造成这个博客似乎有人来的假象？？？</p><h1 id="next主题已更新至5-1-1"><a class="header-anchor" href="#next主题已更新至5-1-1">¶</a>NexT主题已更新至5.1.1</h1><p>由于当年年少无知修改主题的时候都是直接修改 并没有用git 所以升级只能手动合并 特别麻烦<br>这里安利一个用来比较和合并文件和文件夹的软件 Beyond Compare 超级好用<br>当然 由于是手动合并 免不了有点疏漏 如果出现了bug请和我联系或者在底下评论 谢谢w</p><h2 id="文章底部加入版权信息"><a class="header-anchor" href="#文章底部加入版权信息">¶</a>文章底部加入版权信息</h2><p>如果没有特殊说明 本站所有文章均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" rel="external nofollow noopener noreferrer" target="_blank">CC BY-NC-SA 4.0 CN</a> 许可协议<br>顺便求个友链ww</p><h2 id="开启scroll-percent功能"><a class="header-anchor" href="#开启scroll-percent功能">¶</a>开启Scroll Percent功能</h2><p>在返回顶部按钮上加入了阅读进度<br><img src="https://img.leaferx.ink/30773a07b7dd49d9dc9a.jpg" alt=""></p><h2 id="开启save-scroll功能"><a class="header-anchor" href="#开启save-scroll功能">¶</a>开启Save Scroll功能</h2><p>每篇文章的阅读进度都会写入cookies 这样等你返回的时候就能从你退出的地方读起啦</p><h2 id="禁用底部点击小心心功能"><a class="header-anchor" href="#禁用底部点击小心心功能">¶</a>禁用底部点击小心心功能</h2><p>出于代码整洁度和实用性考虑 该功能已被禁用<br>不过最近在构思一个可以统计点赞数量的tag 如果写出来了会写篇文章介绍</p><h2 id="其他细节性改善"><a class="header-anchor" href="#其他细节性改善">¶</a>其他细节性改善</h2><p>如禁用ScrolltoMore功能、解决sidebar内滚动功能（虽然暂时还用不到）等</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;https://img.leaferx.ink/0ea297aaa2ff47b004e7.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="博客通知" scheme="https://leaferx.online/categories/%E5%8D%9A%E5%AE%A2%E9%80%9A%E7%9F%A5/"/>
    
      <category term="更新" scheme="https://leaferx.online/categories/%E5%8D%9A%E5%AE%A2%E9%80%9A%E7%9F%A5/%E6%9B%B4%E6%96%B0/"/>
    
    
  </entry>
  
  <entry>
    <title>利用 Gulp 来压缩你的 Hexo 博客</title>
    <link href="https://leaferx.online/2017/06/16/use-gulp-to-minimize/"/>
    <id>https://leaferx.online/2017/06/16/use-gulp-to-minimize/</id>
    <published>2017-06-16T11:50:05.000Z</published>
    <updated>2018-03-28T10:31:59.776Z</updated>
    
    <content type="html"><![CDATA[<p>这篇文章介绍了如何利用 Gulp 来压缩你的 Hexo 博客的静态文件（ html / css / js ），达到提高访问速度的目的。</p><a id="more"></a><hr><p>这篇博文的大部分内容其实是网上抄来的 链接因为忘记了所以没法放 orz<br>写这篇博文呢主要是因为最近把 NexT 升级了 v5.1.1 里面有些 js 用了 ES6 的语法 但 gulp-uglify 并不支持 ES6<br>于是花了点时间看了下 Gulp 的文档 用 gulp-babel 把 ES6 转成 ES5 这样 uglify 就可以用啦<br><del>（发现自己不喜欢打标点orz）</del></p><hr><h1 id="gulp简介"><a class="header-anchor" href="#gulp简介">¶</a>Gulp简介</h1><p>gulp.js 是一种基于流的，代码优于配置的新一代构建工具。<br>具体前往<a href="http://www.gulpjs.com.cn/" rel="external nofollow noopener noreferrer" target="_blank">官网</a>啦<br>反正是一个基于 node 的用于自动化的工具，和 Grunt 比较类似，不过亮点是 <strong>流</strong> 和 <strong>写代码</strong> ，所以会比 Grunt 快一点。</p><h1 id="准备环境"><a class="header-anchor" href="#准备环境">¶</a>准备环境</h1><p>首先安装 Gulp</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install gulp -g</span><br></pre></td></tr></table></figure><p>然后 cd 到博客的根目录安装压缩静态文件要用的依赖包</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install gulp-minify-css gulp-babel gulp-uglify gulp-htmlmin gulp-htmlclean --save-dev</span><br></pre></td></tr></table></figure><p><del>（这里提倡使用 cnpm）</del><br><em>2018.03.17：</em><br><em>辣鸡 cnpm 装的包各种权限问题 不推荐了哼</em><br><em>等有空写写如何优雅地在国内使用 npm 好了 w</em></p><h1 id="创建gulpfile-js"><a class="header-anchor" href="#创建gulpfile-js">¶</a>创建gulpfile.js</h1><p>在博客的根目录创建文件 gulpfile.js<br>然后粘贴代码</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>);</span><br><span class="line"><span class="keyword">var</span> minifycss = <span class="built_in">require</span>(<span class="string">'gulp-minify-css'</span>);</span><br><span class="line"><span class="keyword">var</span> babel = <span class="built_in">require</span>(<span class="string">'gulp-babel'</span>);</span><br><span class="line"><span class="keyword">var</span> uglify = <span class="built_in">require</span>(<span class="string">'gulp-uglify'</span>);</span><br><span class="line"><span class="keyword">var</span> htmlmin = <span class="built_in">require</span>(<span class="string">'gulp-htmlmin'</span>);</span><br><span class="line"><span class="keyword">var</span> htmlclean = <span class="built_in">require</span>(<span class="string">'gulp-htmlclean'</span>);</span><br><span class="line"></span><br><span class="line">gulp.task(<span class="string">'minify-css'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.src(<span class="string">'./public/**/*.css'</span>)</span><br><span class="line">        .pipe(minifycss())</span><br><span class="line">        .pipe(gulp.dest(<span class="string">'./public'</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.task(<span class="string">'minify-html'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.src(<span class="string">'./public/**/*.html'</span>)</span><br><span class="line">        .pipe(htmlclean())</span><br><span class="line">        .pipe(htmlmin(&#123;</span><br><span class="line">            removeComments: <span class="literal">true</span>,</span><br><span class="line">            minifyJS: <span class="literal">true</span>,</span><br><span class="line">            minifyCSS: <span class="literal">true</span>,</span><br><span class="line">            minifyURLs: <span class="literal">true</span>,</span><br><span class="line">        &#125;))</span><br><span class="line">        .pipe(gulp.dest(<span class="string">'./public'</span>))</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.task(<span class="string">'minify-js'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.src([<span class="string">'./public/**/*.js'</span>, <span class="string">'!./public/**/*.min.js'</span>])</span><br><span class="line">        .pipe(babel(&#123; <span class="attr">presets</span>: [<span class="string">'es2015'</span>] &#125;))</span><br><span class="line">        .pipe(uglify())</span><br><span class="line">        .pipe(gulp.dest(<span class="string">'./public'</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.task(<span class="string">'default'</span>, [<span class="string">'minify-html'</span>, <span class="string">'minify-css'</span>, <span class="string">'minify-js'</span>]);</span><br></pre></td></tr></table></figure><p><strong>注意</strong><br>gulp-babel 只能转换如箭头函数等一部分 ES6 的新特性 对 import 无能为力 如果需要压缩含有 import 特性的代码 需要使用 webpack 或者 browserify 等工具 具体教程网上有 我因为用不到也就没仔细研究</p><h1 id="压缩方法"><a class="header-anchor" href="#压缩方法">¶</a>压缩方法</h1><p>在 hexo g 之后在 cmd 里敲入 gulp 回车就可以啦<br>推荐姿势：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo cl &amp;&amp; hexo g &amp;&amp; gulp &amp;&amp; hexo d</span><br></pre></td></tr></table></figure><p>gulp运行截图<br><img src="https://img.leaferx.ink/86504825e54d397ab0b2.jpg" alt=""></p><p>gulp运行前后比较<br><img src="https://img.leaferx.ink/563fe13572154f249748.jpg" alt=""></p><h1 id="更为推-tou-荐-lan-的姿势"><a class="header-anchor" href="#更为推-tou-荐-lan-的姿势">¶</a>更为推（tou）荐（lan）的姿势</h1><p><em>2018.03.17更新</em><br>打开博客根目录的 <code>package.json</code> ，在 <code>&quot;scripts&quot;</code> 项增加一个 <code>&quot;publish&quot;</code> 命令：</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  //...</span><br><span class="line">  "scripts": &#123;</span><br><span class="line">    //...</span><br><span class="line">    "publish": "hexo cl &amp;&amp; hexo g &amp;&amp; gulp &amp;&amp; hexo d",</span><br><span class="line">    //...</span><br><span class="line">  &#125;</span><br><span class="line">  //...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后每次需要部署的时候只要运行下面命令就可以啦。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run publish</span><br></pre></td></tr></table></figure><p>省了 20 个字符呢 w</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这篇文章介绍了如何利用 Gulp 来压缩你的 Hexo 博客的静态文件（ html / css / js ），达到提高访问速度的目的。&lt;/p&gt;
    
    </summary>
    
      <category term="Hexo折腾" scheme="https://leaferx.online/categories/Hexo%E6%8A%98%E8%85%BE/"/>
    
    
      <category term="Hexo" scheme="https://leaferx.online/tags/Hexo/"/>
    
      <category term="博客" scheme="https://leaferx.online/tags/%E5%8D%9A%E5%AE%A2/"/>
    
      <category term="教程" scheme="https://leaferx.online/tags/%E6%95%99%E7%A8%8B/"/>
    
      <category term="前端" scheme="https://leaferx.online/tags/%E5%89%8D%E7%AB%AF/"/>
    
      <category term="Gulp" scheme="https://leaferx.online/tags/Gulp/"/>
    
  </entry>
  
  <entry>
    <title>MiNLabSys搭建和各种坑</title>
    <link href="https://leaferx.online/2017/06/06/MiNLabSys/"/>
    <id>https://leaferx.online/2017/06/06/MiNLabSys/</id>
    <published>2017-06-06T12:37:19.000Z</published>
    <updated>2018-03-28T10:31:57.389Z</updated>
    
    <content type="html"><![CDATA[<p>MiNLabSys是宁波中学创客空间实验室系统的简称<br>该系统目前已实现中央服务器和门禁系统的部分功能（虽然完成度很低orz）<br>介绍和代码请移步GitHub：<br><a href="https://github.com/MakersInNingZhong/MiNLabSys-Server" rel="external nofollow noopener noreferrer" target="_blank">MakersInNingZhong/MiNLabSys-Server</a><br><a href="https://github.com/MakersInNingZhong/MiNLabSys-Door" rel="external nofollow noopener noreferrer" target="_blank">MakersInNingZhong/MiNLabSys-Door</a></p><p>本文主要着重于搭建该系统时遇到的各种坑</p><p><img src="https://img.leaferx.ink/7231309e5c5412650953.jpg" alt=""></p><a id="more"></a><hr><p>好了按惯例先扯上一会儿 跳过就好w<br>好久不见 我（大概）来月更了orzzz<br>临近期末事情越来越多 各种比赛和社团要收尾 根本没时间刷SICP和习题<br>更何况我又入了C++ Premier Plus的坑<br>所以.....................<br>SICP的第一篇读书笔记可能要鸽很久很久啦（大概高三暑假）（你还真有脸说）<br>当然习题还是会抽空刷的 在GitBook上不定期诈尸<a href="https://leaferx.gitbooks.io/sicp/content/" rel="external nofollow noopener noreferrer" target="_blank">Exersices Solutions of SICP</a><br>公开课也一直在刷 虽然每天看不到十分钟就要睡觉了orz</p><p>真紧张明天我的桌子和椅子就要参加高考了<br>看了一下ZUI DAYS<br>还有88天物竞<br>还有131天选考<br>还有365天高考<br>时间有时候真是令人生厌</p><p>物理还是没有进150名<br>不过暑假要去质心决赛班 终于可以亲眼见到蔡子星啦嘿嘿嘿<br>我爱物理我爱物理我爱物理我爱物理我爱物理我爱物理我爱物理</p><p>物理免修后多出来五节自修课最近浪得很开心 刷刷题看看书泡泡实验室什么的<br>但不知道为什么时间还是那么少 事情还是那么多</p><p>不知不觉扯了这么多orz 还是回归一下正题吧</p><p>人生中第一次在Github上写这么长的英文README<br>人生中第一次Arduino写多文件模块化程序（没有用类啦因为觉得没必要orz）</p><p>这个项目史无前例地遇到了各种巨坑 坑多到报警<br>到现在都还没有完全解决（大概也没空解决了呃）</p><p>其实本来这个项目是很宏大的 还计划了智能窗帘、智能橱柜、分布式传感器系统<br>但因为人手和时间的原因 可能就只能这样了....<br>创客空间也没几个人真正在做事情 无奈</p><p>这个项目目前已经参加了宁波中科院创客空间举办的比赛 相关参赛视频和链接什么的在文末</p><p>好了 接下来 我们谈谈各种坑</p><hr><h1 id="服务器部分"><a class="header-anchor" href="#服务器部分">¶</a>服务器部分</h1><p>来张（半）全家福<br><img src="https://img.leaferx.ink/5547dd776dcc215b7e13.jpg" alt=""><br>从左下到右上分别是 ESP8266、MFRC522、Arduino Uno、Banana Pi</p><p>服务器部分我采用的是香蕉派（最经典的那款）（也就是最弱的那款）（连板载WiFi都没有）<br>没错 就是这么简单的一个node应用 我都遇到了巨坑<br>而且第一个坑就是在安装node上</p><p>首先说明 我用的系统是<strong>32位</strong>的Raspbian jessie for bananapi<br>在安装之前 我就看见网上大佬们各种警告 <strong>不要用包管理器安装</strong><br>那好吧 那就下载源码编译吧<br>可我万万没想到的是 我光make就花了整整一天的时间<br>喵喵喵？？？<br>更可怕的是 我make install了整整一天都没装上.....<br>CPU一直跑在100%但我并不知道它到底在干啥 只能^C了<br>最后 我是下载了别人编译好的二进制包才成功装了上去</p><p>第二个坑是对这次开发影响最小的但是让我感受到了绝望<br>我本来想打算借着这个项目接触一下MongoDB<br>于是我在开始做之前看了大半个月的教程和文档<br>好了你们应该猜到什么了吧<br><strong>MongoDB只支持64位系统！！！</strong><br><strong>这只香蕉派只有32位系统镜像！！！（至少我没找到64位）</strong><br>那好吧 我大半个月只能算白看了 毕竟再次应用肯定不知道要等到什么时候去到时候肯定早就忘了<br>于是只能屈服于MySQL 安慰自己关系型数据库挺好的 稳定安全又好弄（雾）</p><p>第三个坑是一个十分naive的坑（咳）<br>node和mysql连接的库只有英文文档 还写得有点乱糟糟的<br>我修改了一下复制的示例 然后发现如果查询命中就没问题 但如果没有命中就会报错 直接退出<br>当时以为是库的原因 没有命中就throw error<br>然后就各种看文档和怀疑自己的英语水平<br>直到我看见了<code>if(err) throw err;</code><br>........<br>于是我神经错乱到在回调函数外写了try-carch..........<br>然后我看到了错误提示<strong>Cannot read property of undefined</strong><br>.................<br>我可能是要重新学一遍js<br>总结：</p><ol><li>类型检查一定要做 尤其是和数据库相关的时候</li><li>遇到错误千万要仔细读几遍 确定了错哪再去调bug<br>不过这次是因为由于error是在回调函数里面被抛出 所以错误信息被模块又封装了一层所以特别不起眼orzzz</li></ol><p>迈过了三座大坑 我写完了服务端<br>但是 我万万没有想到的是 这还只是个开始......</p><hr><h1 id="客户端部分"><a class="header-anchor" href="#客户端部分">¶</a>客户端部分</h1><p><img src="https://img.leaferx.ink/59f1e27eb16e210cb2ee.jpg" alt=""><br>MFRC522和ESP8266</p><p>调MFRC522一切顺利 用了<a href="https://github.com/miguelbalboa/rfid" rel="external nofollow noopener noreferrer" target="_blank">@miguelbalboa</a>的库<br>谢天谢地 这是我最靠谱的时刻</p><p>然后就是ESP8266了 这家伙真我是见过的最难调的模块<br>尤其是当你一开始没有开软串口来调试的时候<br>（不要问我为什么不用软串口连ESP8266 软串口波特率最高只有9600...）</p><p>我这个项目是使用HTTP协议完成客户端和服务端的通信<br>数据交换格式是json<br>这也是我整个项目最作死的地方......</p><p>数据只有十几二十字节 但加上了HTTP头瞬间变成了两百字节...<br>然后Arduino就瞬间爆炸<br>什么串口缓冲区溢出啦 内存不足啦 全都来了<br>关键是这个错误没有报错一开始还意识不到 白做了很多debug尝试</p><p>第一个坑就是串口缓冲区溢出<br>而且这个坑让我明白了 什么叫做为什么调通了程序都不知道自己做了什么操作</p><p>一开始我读取数据时 使用的函数大概是这样的</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> (ESP8266.available() &gt; <span class="number">0</span>)&#123;</span><br><span class="line">    msg += <span class="keyword">char</span>(ESP8266.read());</span><br><span class="line">    delay(<span class="number">4</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后一般只接收到70来个字节就收不到了（Arduino默认缓冲区只有64字节）<br>很显然是缓冲区溢出了</p><p>但很神奇的是 我把缓冲区调大也并没有什么卵用 消息始终收不全<br>尤其是当我把缓冲区调到256字节以上的时候 毛都收不到了.........</p><p>没办法 我只能从接收函数下手了<br>我怀疑接收函数一个一个字节实在太慢了尤其还停顿了4毫秒（虽然我把delay注释了也读不全虽然会稍微好一点）<br>然后我就看文档有没有直接收整个缓冲区的函数 于是我看到了readString<br>虽然这个操作把我带向了另外一个深坑</p><p>于是我的接收函数就变成了这样</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ESP8266_ReadData</span><span class="params">(String&amp; temp, <span class="keyword">int</span> delay_time = <span class="number">4</span>)</span> </span>&#123;</span><br><span class="line">    <span class="meta">#<span class="meta-keyword">ifdef</span> USE_DEBUG_MODE</span></span><br><span class="line">        DEBUG.println(<span class="string">"Reading data..."</span>);</span><br><span class="line">    <span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">    <span class="keyword">while</span>(!ESP8266.available());</span><br><span class="line">    <span class="keyword">while</span>(ESP8266.available())&#123;</span><br><span class="line">        temp += ESP8266.readString();</span><br><span class="line">        delay(delay_time);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>看上去非常正确是不是 可还是不行<br>但当我把缓冲区调到128字节的时候就特喵的行了......<br>work perfectly<br>这让我很绝望....<br>到底是为什么orz</p><p>第二个坑又是文档的问题<br>我在用ArduinoJson库的时候 用了DynamicBuffer<br>可谁知道DynamicBuffer是不会自动释放的......<br>于是立马内存溢出 运行几轮后就程序错乱<br>当时不是很肯定是ArduinoJson的问题<br>而且我又看了两遍文档也注意到什么 直到我搜了Issue才解决<br>只要把DynamicBuffer定义在全局就行了<br>可这么重要的事情为什么就不能写在文档里呢<br>要么是我太小白了？（非常有可能orz）</p><p>好了 来到最后一个巨坑 <strong>内！存！不！足！</strong><br>对这个巨坑 我想到的唯一办法就是上Arduino Mega2560<br>实在解决不了了</p><p>为了解决第一个坑 我（迫不得已）用了String类（或者说只是因为懒而已String用起来好方便啊qwqqqq）<br>然后？然后内存就炸了</p><p>虽然明明我删掉了所有调试信息后烧进去提示只占用了30%左右的内存<br>可能我局部String用得实在太多了吧<br>逼得我传String只能传引用（这才是正确的写法好吗直接返回String是真的非常小白的做法） 于是程序终于勉勉强强地跑起来了</p><p>但是接下来就是我最绝望的时刻<br>因为这个程序 它不稳定<br>不稳定到什么程度呢<br>你完全不知道什么时候它是正常运行的<br>有的时候完全没法用<br>有的时候只能跑一轮两轮<br>极少数时候能一直正常运行<br>所以我按了无数遍的重启.........<br>最难受的是我还看不见调试信息 为了省内存....</p><p>总结：没事别拿Uno折腾自己 该上Mega就果断上 不要和内存优化死磕 尤其是当你还在用String类的时候</p><hr><p>其实还踩了很多很多小坑 但这篇充满吐槽风格的文章还是就到这吧<br>已经毛4000字了....第一次一口气写这么多....</p><p>好了 最后附点视频</p><p><a href="http://v.youku.com/v_show/id_XMjc5NDQyODAzMg" rel="external nofollow noopener noreferrer" target="_blank">调试信息还活着的时候拍的演示视频</a></p><p><a href="http://mp.weixin.qq.com/s?__biz=MzI3MTEwMDgwMg==&amp;mid=2655536407&amp;idx=1&amp;sn=d77da1e4def7710853bf3e9be177ba68&amp;chksm=f17a1bfac60d92ec0f2e8706d13ee2fdd38b884bdd901df14464de7790bddb1bef3231f92480&amp;mpshare=1&amp;scene=22&amp;srcid=0605oOWAMFhC8JmiVGsQCnHA#rd" rel="external nofollow noopener noreferrer" target="_blank">最终的比赛视频</a></p><p>晚好<br>2017/6/7 20:30<br>LEAFERx</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;MiNLabSys是宁波中学创客空间实验室系统的简称&lt;br&gt;
该系统目前已实现中央服务器和门禁系统的部分功能（虽然完成度很低orz）&lt;br&gt;
介绍和代码请移步GitHub：&lt;br&gt;
&lt;a href=&quot;https://github.com/MakersInNingZhong/MiNLabSys-Server&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;MakersInNingZhong/MiNLabSys-Server&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://github.com/MakersInNingZhong/MiNLabSys-Door&quot; rel=&quot;external nofollow noopener noreferrer&quot; target=&quot;_blank&quot;&gt;MakersInNingZhong/MiNLabSys-Door&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文主要着重于搭建该系统时遇到的各种坑&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.leaferx.ink/7231309e5c5412650953.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Notes of SICP 0</title>
    <link href="https://leaferx.online/2017/04/23/SICP-note-0/"/>
    <id>https://leaferx.online/2017/04/23/SICP-note-0/</id>
    <published>2017-04-23T03:30:32.000Z</published>
    <updated>2018-03-28T10:31:58.841Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>“世之奇伟、瑰怪、非常之观，常在于险远，而人之所罕至焉，故非有志者不能至也。”<br>王安石《游褒禅山记》</p></blockquote><p>这是《计算机程序的构造和解释》（Structure and Interpretation of Computer Programs）笔记系列的第0篇<br><img src="https://img.leaferx.ink/d781a9ca917e7c8aa863.jpg" alt="book cover"></p><a id="more"></a><p>是的我终于来诈尸了 好久不见<br>考完学考选考感觉自己像个废人 然后5.1物理省赛 最近是真的忙<br>但梦想不能丢对吧 于是我打算开始了这本书的笔记（其实只是算法导论实在刷不下去了orzzz）<br>这本书大概算是圈中公认的（至少是知乎qwq）一本计算机编程入门奇书<br>书的内容按大佬们的说法是各种抽象概念和抽象方法 是一本讲述控制复杂度方法的入门书<br>同按大佬的说法 阅读这本书的最终目的是抓住计算机中的神灵<br>其实这本书我断断续续阅读了也大概有两个月了 算是勉强看完了前三章 虽然是按照阅读《xxx从入门到精通》的节奏<br>所以决定痛改一下前非 认真地啃完这本书<br>第0篇主要写一些准备内容吧比如环境搭建啊还有一些学习资源啊什么的<br>嗯 算法导论再见<br>好了以上是瞎吐槽 跳过就好<br>顺便放张图 共勉<br><img src="https://img.leaferx.ink/eabbafb0ff7ffe589cd2.jpg" alt="0-0"></p><hr><h2 id="introduction"><a class="header-anchor" href="#introduction">¶</a>Introduction</h2><p>我用的是机械工业出版社和中信出版社出版的SICP中文译本<br><a href="https://book.douban.com/subject/1148282/" rel="external nofollow noopener noreferrer" target="_blank">豆瓣链接</a></p><blockquote><p><strong>带着崇敬和赞美，将本书献给活在计算机里的神灵。</strong><br>“我认为，在计算机科学中保持计算中的趣味性是特别重要的事情。这一学科在起步时包含着趣味性。当然，那些付钱的客户们时常觉得受了骗。一段时 间之后，我们开始严肃地看待他们的抱怨。我们开始感觉到，自己真的像是要负起成功地、无差错地、完美地使用这些机器的责任。我不认为我们可以做到这些。我 认为我们的责任是拓展这一领域，将其发展到新的方向，并在自己的家里保持趣味性。我希望计算机科学的领域绝不要丧失其趣味意识。最重要的是，我希望我们不 要变成传道士，不要认为你是兜售圣经的人，世界上这种人已经太多了。你所知道的有关有关计算的东西，其他人也都能学到。绝不要认为似乎成功计算的钥匙就掌 握在你的手里。你所掌握的，也是我认为并希望的，也就是智慧：那种看到这一机器比你第一次站在它面前时能做得更多的能力，这样你才能将它向前推进。”<br><em>Alan J. Perlis</em></p></blockquote><p>目录构成：</p><ul><li>构造过程抽象（Building Abstractions with Procedures）</li><li>构造数据抽象（Building Abstractions with Data）</li><li>模块化、对象和状态（Modularity, Objects, and State）</li><li>元语言抽象（Meta-Linguistic Abstraction）</li><li>寄存器机器里的计算（Register Machine' Model of Control）</li></ul><h2 id="environment"><a class="header-anchor" href="#environment">¶</a>Environment</h2><p>我使用Racket 6.8 64位作为实验和习题环境<br>Racket的安装包可以在<a href="http://racket-lang.org/" rel="external nofollow noopener noreferrer" target="_blank">Racket官网</a>获得<br>安装完后 可以使用由Neil大佬提供的SICP语言包进行编程<br>（Racket看上去是一个很好玩的语言平台 有空可以去深入一下）<br>（好吧我其实只是实在搞不懂MIT-GNU Scheme...）<br>安装SICP语言包的方法：</p><ol><li>打开DrRacket</li><li>在上方编辑框内将 #lang racket 改为 #lang planet neil/sicp 并点上方Run</li><li>等下载好安装好后 重启DrRacket</li><li>点击上方菜单栏 Language =&gt; Choose language... =&gt; Teaching Languagues 选择下方的SICP 然后点OK</li><li>完成 会看到下方编辑框显示：Language: SICP (PLaneT 1.18); memory limit: xxx MB. 如果没有请点一下Run或者重启 接下来就可以在下方编辑框编写程序了</li></ol><h2 id="resources"><a class="header-anchor" href="#resources">¶</a>Resources</h2><p><a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/" rel="external nofollow noopener noreferrer" target="_blank">MIT公开课</a>（英文）<br><a href="https://github.com/DeathKing/Learning-SICP" rel="external nofollow noopener noreferrer" target="_blank">MIT公开课视频翻译项目</a><br><a href="http://www.math.pku.edu.cn/teachers/qiuzy/progtech/" rel="external nofollow noopener noreferrer" target="_blank">北大课程资料</a>（使用SICP作为课本）<br><a href="https://www.zhihu.com/question/26549715" rel="external nofollow noopener noreferrer" target="_blank">知乎问题：《计算机程序的构造和解释（SICP）》讨论的核心问题是什么？</a><br>还有许多大佬的笔记 搜索关键词：SICP 笔记 就行</p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;“世之奇伟、瑰怪、非常之观，常在于险远，而人之所罕至焉，故非有志者不能至也。”&lt;br&gt;王安石《游褒禅山记》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是《计算机程序的构造和解释》（Structure and Interpretation of Computer Programs）笔记系列的第0篇&lt;br&gt;
&lt;img src=&quot;https://img.leaferx.ink/d781a9ca917e7c8aa863.jpg&quot; alt=&quot;book cover&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Notes of SICP" scheme="https://leaferx.online/categories/Notes-of-SICP/"/>
    
    
      <category term="笔记" scheme="https://leaferx.online/tags/%E7%AC%94%E8%AE%B0/"/>
    
      <category term="编程" scheme="https://leaferx.online/tags/%E7%BC%96%E7%A8%8B/"/>
    
      <category term="学习" scheme="https://leaferx.online/tags/%E5%AD%A6%E4%B9%A0/"/>
    
      <category term="计算机程序的构造和解释" scheme="https://leaferx.online/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%9E%84%E9%80%A0%E5%92%8C%E8%A7%A3%E9%87%8A/"/>
    
      <category term="SICP" scheme="https://leaferx.online/tags/SICP/"/>
    
  </entry>
  
  <entry>
    <title>书单  /  BookList</title>
    <link href="https://leaferx.online/2017/01/27/Books/"/>
    <id>https://leaferx.online/2017/01/27/Books/</id>
    <published>2017-01-27T01:30:26.000Z</published>
    <updated>2018-05-17T05:15:32.488Z</updated>
    
    <content type="html"><![CDATA[<p>会频繁持续更新！！！会频繁持续更新！！！会频繁持续更新！！！<br>也会逐渐补上一些以前看的书，时间记不清那也就随便写啦<br>格式为：[入手时间] + [书名] + [作者]<br>点击书名会进入这本书的豆瓣页面<br><em>较早期的书本日期统一注为2015.01</em><br>手机党戳右下角的悬浮按钮可以打开目录</p><!--书名前面*越多代表推荐程度越高哦--><a id="more"></a><h1 id="专业向"><a class="header-anchor" href="#专业向">¶</a>专业向</h1><h2 id="计算机"><a class="header-anchor" href="#计算机">¶</a>计算机</h2><ul><li><a href="https://book.douban.com/subject/25798102/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  MongoDB权威指南（第2版）  [美] 霍多罗夫 (Kristina Chodorow)</a></li><li><a href="https://book.douban.com/subject/24744217/" rel="external nofollow noopener noreferrer" target="_blank">2017.11  JavaScript设计模式  [美] Addy Osmani</a></li><li><a href="https://book.douban.com/subject/4822685/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  编码：隐匿在计算机软硬件背后的语言  [美] Charles Petzold</a></li><li><a href="https://book.douban.com/subject/26598045/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  Web全栈工程师的自我修养  余果</a></li><li><a href="https://book.douban.com/subject/26546893/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  精通Linux（第2版）  [美] Brian Ward</a></li><li><a href="https://book.douban.com/subject/26697422/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  深入理解JavaScript  [美] Axel Rauschmayer</a></li><li><a href="https://book.douban.com/subject/25827178/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  Raspberry Pi快速入门指南  [美] Maik Schmidt</a></li><li><a href="https://book.douban.com/subject/1148282/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  计算机程序的构造和解释  [美] Harold Abelson等</a></li><li><a href="https://book.douban.com/subject/25894685/" rel="external nofollow noopener noreferrer" target="_blank">2016.10  啊哈！算法  啊哈磊</a></li><li><a href="https://book.douban.com/subject/26822106/" rel="external nofollow noopener noreferrer" target="_blank">2016.09  图解密码技术（第3版）  [日] 结城浩</a></li><li><a href="https://book.douban.com/subject/20432061/" rel="external nofollow noopener noreferrer" target="_blank">2015.11  算法导论  [美] Thomas H.Cormen等</a></li><li><a href="https://book.douban.com/subject/25902102/" rel="external nofollow noopener noreferrer" target="_blank">2015.09  算法竞赛入门经典（第2版）  刘汝佳</a></li><li><a href="https://book.douban.com/subject/20254543/" rel="external nofollow noopener noreferrer" target="_blank">2015.09  算法竞赛入门经典：训练指南  刘汝佳</a></li><li><a href="https://book.douban.com/subject/25960095/" rel="external nofollow noopener noreferrer" target="_blank">2015.09  爱上Arduino：学Arduino玩转Kinect制作项目  Enrique Ramos Melgar等</a></li><li><a href="https://book.douban.com/subject/4710825/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  妙趣横生的算法  杨峰</a></li><li><a href="https://book.douban.com/subject/26870223/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  Arduino高级开发权威指南  [美] Steven F.Barrett</a></li><li><a href="https://book.douban.com/subject/25966259/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  CSS高效开发实战  谢郁</a></li><li><a href="https://book.douban.com/subject/26870253/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  Arduino晋级应用指南  [美] Emery Premeaux</a></li><li><a href="https://book.douban.com/subject/25774789/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  jQuery权威指南(第2版)  陶国荣</a></li><li><a href="https://book.douban.com/subject/26108418/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  Arduino魔法书  [美] Jeremy Blum</a></li><li>2015.01  AVR单片机入门与速成攻略  高显生 9787111461555</li></ul><h2 id="数学"><a class="header-anchor" href="#数学">¶</a>数学</h2><ul><li><a href="https://book.douban.com/subject/5276440/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  线性代数  [美] Steven J. Leon</a></li><li><a href="https://book.douban.com/subject/26688502/" rel="external nofollow noopener noreferrer" target="_blank">2016.03  散度、旋度、梯度释义（图解版）  [美] Schey, H.M.</a></li><li>2016.02  离散数学  许克祥等  9787512415942</li><li><a href="https://book.douban.com/subject/26577905/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  数学建模（原书第5版）  [美] Frank R. Giordano等</a></li><li><a href="https://book.douban.com/subject/24697895/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  我怎样解题  单墫</a></li><li><a href="https://book.douban.com/subject/10726262/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  初等数论  陈景润</a></li></ul><h2 id="物理"><a class="header-anchor" href="#物理">¶</a>物理</h2><ul><li><a href="https://book.douban.com/subject/10517521/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  数学物理方法  [德] 顾樵</a></li><li><a href="https://book.douban.com/subject/2060002/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  Introduction to Electrodynamics (3rd Edition)  [美] David J. Griffiths</a></li><li><a href="https://book.douban.com/subject/2059252/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  力学 [俄] П.Д.朗道</a></li><li><a href="https://book.douban.com/subject/1943513/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  经典力学  沈惠川</a></li><li><a href="https://book.douban.com/subject/24715603/" rel="external nofollow noopener noreferrer" target="_blank">2015.11  费恩曼物理学讲义（第1卷）  [美] R.P.Feynman</a></li><li><a href="https://book.douban.com/subject/24371364/" rel="external nofollow noopener noreferrer" target="_blank">2015.11  费恩曼物理学讲义（第2卷）  [美] R.P.Feynman</a></li><li><a href="https://book.douban.com/subject/24722484/" rel="external nofollow noopener noreferrer" target="_blank">2015.11  费恩曼物理学讲义（第3卷）  [美] R.P.Feynman</a></li><li><a href="https://book.douban.com/subject/1896907/" rel="external nofollow noopener noreferrer" target="_blank">2015.04  电路  邱关源等</a></li><li><a href="https://book.douban.com/subject/1707050/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  狭义与广义相对论浅说  [美] 爱因斯坦</a></li></ul><h2 id="化学"><a class="header-anchor" href="#化学">¶</a>化学</h2><ul><li><a href="https://book.douban.com/subject/1160337/" rel="external nofollow noopener noreferrer" target="_blank">2015.11  无机化学（第三版）上册  武汉大学 / 吉林大学</a></li><li><a href="https://book.douban.com/subject/1088840/" rel="external nofollow noopener noreferrer" target="_blank">2015.11  无机化学（第三版）下册  武汉大学 / 吉林大学</a></li></ul><h2 id="其他"><a class="header-anchor" href="#其他">¶</a>其他</h2><ul><li><a href="https://book.douban.com/subject/26425498/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  Cinema 4D完全学习手册  TVart培训基地</a></li></ul><hr><h1 id="非专业向"><a class="header-anchor" href="#非专业向">¶</a>非专业向</h1><h2 id="科普向"><a class="header-anchor" href="#科普向">¶</a>科普向</h2><ul><li><a href="https://book.douban.com/subject/27054267/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  黑洞不是黑的  [英] 史蒂芬·霍金</a></li><li><a href="https://book.douban.com/subject/27156306/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  现实不似你所见  [意] 卡洛·罗韦利</a></li><li><a href="https://book.douban.com/subject/26735272/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  费曼讲演录  [美] 理查德·费曼</a></li><li><a href="https://book.douban.com/subject/26420533/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  度量  [美] 保罗·洛克哈特</a></li><li><a href="https://book.douban.com/subject/26685012/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  希格斯粒子是如何找到的  [英] 乔恩·巴特沃思</a></li><li><a href="https://book.douban.com/subject/26740091/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  爱与数学  [美] Edward Frenkel</a></li><li><a href="https://book.douban.com/subject/26365491/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  程序是怎样跑起来的  [日] 矢泽久雄</a></li><li><a href="https://book.douban.com/subject/26397183/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  计算机是怎样跑起来的  [日] 矢泽久雄</a></li><li><a href="https://book.douban.com/subject/26772731/" rel="external nofollow noopener noreferrer" target="_blank">2016.10  七堂极简物理课  [意] 卡洛·罗韦利</a></li><li><a href="https://book.douban.com/subject/26785898/" rel="external nofollow noopener noreferrer" target="_blank">2016.07  强力与弱力  [日] 大栗博司</a></li><li><a href="https://book.douban.com/subject/26673315/" rel="external nofollow noopener noreferrer" target="_blank">2016.07  庞加莱猜想  [日] 春日真人</a></li><li><a href="https://book.douban.com/subject/26284518/" rel="external nofollow noopener noreferrer" target="_blank">2016.05  超弦理论  [日] 大栗博司</a></li><li><a href="https://book.douban.com/subject/26352270/" rel="external nofollow noopener noreferrer" target="_blank">2016.03  《三体》中的物理学  李淼</a></li><li><a href="https://book.douban.com/subject/26320244/" rel="external nofollow noopener noreferrer" target="_blank">2016.02  巫师、外星人和星舰  [美] Charles L. Adler</a></li><li><a href="https://book.douban.com/subject/22218092/" rel="external nofollow noopener noreferrer" target="_blank">2016.02  Microcosmos  [德] Harald Fritzsch</a></li><li><a href="https://book.douban.com/series/21451" rel="external nofollow noopener noreferrer" target="_blank">2015.03  理解科学丛书 （截止至2017年1月28日共有11册）</a></li><li><a href="https://book.douban.com/subject/26184242/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  无穷的开始  [英] David Deutsch</a></li><li><a href="https://book.douban.com/subject/26268375/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  电子，电子！谁来拯救摩尔定律？  张天蓉</a></li><li><a href="https://book.douban.com/subject/26688540/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  光影世界：电影中的物理学  李耀俊</a></li><li><a href="https://book.douban.com/subject/21458724/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  电的旅程 探索人类驾驭电子的历史过程  张大凯</a></li><li><a href="https://book.douban.com/subject/26420540/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  平面宇宙  [美] A. K. 杜德尼</a></li><li><a href="https://book.douban.com/subject/25962840/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  反欺骗的艺术  [美] 米特尼克</a></li><li><a href="https://book.douban.com/subject/26387796/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  寻找薛定谔的猫  [英] John Gribbin</a></li><li><a href="https://book.douban.com/subject/26171042/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  悖论：破解科学史上最复杂的9大谜团  [英] Jim Al-Khalili</a></li><li><a href="https://book.douban.com/subject/26220204/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  生活中的概率趣事  [瑞典] Peter Olofsson</a></li><li><a href="https://book.douban.com/subject/25962826/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  反入侵的艺术——黑客入侵背后的真实故事  [美] 米特尼克等</a></li><li><a href="https://book.douban.com/subject/26631600/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  欲望都市数学版：城市生活中的数学建模  [美] John A. Adam</a></li><li><a href="https://book.douban.com/subject/26107771/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  化学元素之旅  [美] Tom Jackson</a></li></ul><h2 id="社科文学向"><a class="header-anchor" href="#社科文学向">¶</a>社科文学向</h2><ul><li><a href="https://book.douban.com/subject/6712255/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  天真的人类学家  [英] 奈吉尔·巴利</a></li><li><a href="https://book.douban.com/subject/26644777/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  导读弗洛伊德  [英] 帕梅拉·瑟齐韦尔</a></li><li><a href="https://book.douban.com/subject/26286751/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  文学阅读指南  [英] 特里·伊格尔顿</a></li><li><a href="https://book.douban.com/subject/26893046/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  诗的八堂课  江弱水</a></li><li><a href="https://book.douban.com/subject/26897993/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  古代汉语常识  王力</a></li><li><a href="https://book.douban.com/subject/26314063/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  斯坦福极简经济学  [美] 蒂莫西‧泰勒</a></li><li><a href="https://book.douban.com/subject/1012611/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  乌合之众：大众心理研究  [法] Gustave Le Bon</a></li><li><a href="https://book.douban.com/subject/25935944/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  查拉图斯特拉如是说  [德] Friedrich Nietzsche</a></li><li><a href="https://book.douban.com/subject/24733022/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  莱布尼茨不是黄油饼干  [德] 米歇尔·施密特-所罗门等</a></li><li><a href="https://book.douban.com/subject/25746237/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  生命之轮  [美] 伊丽莎白·库伯勒-罗斯等</a></li><li><a href="https://book.douban.com/subject/5503739/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  哲学的门槛  [英] 奈杰尔·沃伯顿</a></li><li><a href="https://book.douban.com/subject/25953929/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  一战简史  [英]诺曼·斯通</a></li></ul><h2 id="艺术向"><a class="header-anchor" href="#艺术向">¶</a>艺术向</h2><ul><li><a href="https://book.douban.com/subject/4230237/" rel="external nofollow noopener noreferrer" target="_blank">2016.05  设计中的设计  [日] 原研哉</a></li><li><a href="https://book.douban.com/subject/5323008/" rel="external nofollow noopener noreferrer" target="_blank">2015.05  超越平凡的平面设计  [美] John McWade</a></li><li><a href="https://book.douban.com/subject/3323633/" rel="external nofollow noopener noreferrer" target="_blank">2015.05  写给大家看的设计书（第3版）  [美] Robin Williams</a></li></ul><h2 id="诗"><a class="header-anchor" href="#诗">¶</a>诗</h2><ul><li><a href="https://book.douban.com/subject/26747142/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  自由 ［爱尔兰］萨缪尔·贝克特</a></li><li><a href="https://book.douban.com/subject/22163516/" rel="external nofollow noopener noreferrer" target="_blank">2017.03  云雀叫了一整天  木心</a></li><li><a href="https://book.douban.com/subject/5363277/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  西班牙三棵树  木心</a></li><li><a href="https://book.douban.com/subject/26959009/" rel="external nofollow noopener noreferrer" target="_blank">2016.09  面朝大海 春暖花开  海子</a></li><li><a href="https://book.douban.com/subject/6975925/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  设计诗  朱赢椿</a></li><li><a href="https://book.douban.com/subject/6534893/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  暴风雨使我安睡  顾城</a></li><li><a href="https://book.douban.com/subject/6534894/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  我会像青草一样呼吸  顾城</a></li><li><a href="https://book.douban.com/subject/6534895/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  走了一万一千里路  顾城</a></li></ul><h2 id="影集"><a class="header-anchor" href="#影集">¶</a>影集</h2><ul><li><a href="https://book.douban.com/subject/20424613/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  南法航线  Pano</a></li><li><a href="https://book.douban.com/subject/25913058/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  我爱这哭不出来的浪漫 严明</a></li><li><a href="https://book.douban.com/subject/26237097/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  尔本 安东尼</a></li></ul><h2 id="散文杂文"><a class="header-anchor" href="#散文杂文">¶</a>散文杂文</h2><ul><li><a href="https://book.douban.com/subject/27024398/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  阅读是一座随身携带的避难所  [英]毛姆</a></li><li><a href="https://book.douban.com/subject/20427187/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  看见  柴静</a></li><li><a href="https://book.douban.com/subject/26700416/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  野草  鲁迅</a></li><li><a href="https://book.douban.com/subject/27039598/" rel="external nofollow noopener noreferrer" target="_blank">2017.09  人间草木 汪曾祺</a></li><li><a href="https://book.douban.com/subject/1054685/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  沉默的大多数 王小波</a></li><li><a href="https://book.douban.com/subject/26920390/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  自由的夜行  史铁生</a></li><li><a href="https://book.douban.com/subject/26278687/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  皮囊  蔡崇达</a></li><li><a href="https://book.douban.com/subject/6021440/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  黑客与画家  [美] Paul Graham</a></li><li><a href="https://book.douban.com/subject/4282084/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  论摄影  [美] 苏珊·桑塔格</a></li><li><a href="https://book.douban.com/subject/26722503/" rel="external nofollow noopener noreferrer" target="_blank">2016.10  我的精神家园  王小波</a></li><li><a href="https://book.douban.com/subject/19958089/" rel="external nofollow noopener noreferrer" target="_blank">2016.05  我们仨  杨绛先生</a></li><li><a href="https://book.douban.com/subject/26609776/" rel="external nofollow noopener noreferrer" target="_blank">2016.05  最糟的宇宙，最好的地球  刘慈欣</a></li><li><a href="https://book.douban.com/subject/5327697/" rel="external nofollow noopener noreferrer" target="_blank">2016.02  橙  安东尼</a></li><li><a href="https://book.douban.com/subject/20424614/" rel="external nofollow noopener noreferrer" target="_blank">2016.01  红  安东尼</a></li><li><a href="https://book.douban.com/subject/5264089/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  痕记  痕痕</a></li><li><a href="https://book.douban.com/subject/3995526/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  目送  龙应台</a></li><li><a href="https://book.douban.com/subject/25745152/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  愿风裁尘  郭敬明</a></li><li><a href="https://book.douban.com/subject/25862448/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  怀石逾沙  郭敬明</a></li><li><a href="https://book.douban.com/subject/25855964/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  守岁白驹  郭敬明</a></li><li><a href="https://book.douban.com/subject/3344676/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  常识  梁文道</a></li><li><a href="https://book.douban.com/subject/25922430/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  不辩，是一种智慧  林清玄</a></li><li><a href="https://book.douban.com/subject/20413794/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  眠空  安妮宝贝</a></li><li><a href="https://book.douban.com/subject/25931540/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  告白与告别  韩寒</a></li><li><a href="https://book.douban.com/subject/21318055/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  通稿二零零三  韩寒</a></li><li><a href="https://book.douban.com/subject/25934119/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  万万没想到  有时右逝等</a></li></ul><h2 id="小说"><a class="header-anchor" href="#小说">¶</a>小说</h2><ul><li><a href="https://book.douban.com/subject/27078077/" rel="external nofollow noopener noreferrer" target="_blank">2018.05  高老头  [法] 巴尔扎克</a></li><li><a href="https://book.douban.com/subject/10539805/" rel="external nofollow noopener noreferrer" target="_blank">2018.05  捕鼠器  [英] 阿加莎·克里斯蒂</a></li><li><a href="https://book.douban.com/subject/27041504/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  少数派报告  [美] 菲利普·迪克</a></li><li><a href="https://book.douban.com/subject/6345736/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  呼啸山庄  [英] 艾米莉·勃朗特</a></li><li><a href="https://book.douban.com/subject/2158161/" rel="external nofollow noopener noreferrer" target="_blank">2018.03  世界尽头与冷酷仙境  [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/27070488/" rel="external nofollow noopener noreferrer" target="_blank">2018.01  围城  钱锺书</a></li><li><a href="https://book.douban.com/subject/26276279/" rel="external nofollow noopener noreferrer" target="_blank">2018.01  苦妓回忆录  [哥伦比亚] 加西亚·马尔克斯</a></li><li><a href="https://book.douban.com/subject/2158161/" rel="external nofollow noopener noreferrer" target="_blank">2018.01  世界尽头与冷酷仙境 [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/27123582/" rel="external nofollow noopener noreferrer" target="_blank">2018.01  刀锋  [英] 毛姆</a></li><li><a href="https://book.douban.com/subject/26451351/" rel="external nofollow noopener noreferrer" target="_blank">2018.01  爱情和其他魔鬼  [哥伦比亚] 加西亚·马尔克斯</a></li><li><a href="https://book.douban.com/subject/10554709/" rel="external nofollow noopener noreferrer" target="_blank">2018.01  第二十二条军规  [美] 约瑟夫·海勒</a></li><li><a href="https://book.douban.com/subject/5988624/" rel="external nofollow noopener noreferrer" target="_blank">2017.12  远山淡影  [英] 石黑一雄</a></li><li><a href="https://book.douban.com/subject/27081842/" rel="external nofollow noopener noreferrer" target="_blank">2017.11  手机  [美] 斯蒂芬·金</a></li><li><a href="https://book.douban.com/subject/27041533/" rel="external nofollow noopener noreferrer" target="_blank">2017.11  仿生人会梦见电子羊吗？  [美] 菲利普·迪克</a></li><li><a href="https://book.douban.com/subject/25965026/" rel="external nofollow noopener noreferrer" target="_blank">2017.11  天使与魔鬼  [美] 丹·布朗</a></li><li><a href="https://book.douban.com/subject/6789551/" rel="external nofollow noopener noreferrer" target="_blank">2017.09  不存在的骑士 [意] 伊塔洛·卡尔维诺</a></li><li><a href="https://book.douban.com/subject/25965021/" rel="external nofollow noopener noreferrer" target="_blank">2017.09  达·芬奇密码  [美] 丹·布朗</a></li><li><a href="https://book.douban.com/subject/27063487/" rel="external nofollow noopener noreferrer" target="_blank">2017.09  我们  [俄] 尤金·扎米亚金</a></li><li><a href="https://book.douban.com/subject/27017396/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  国王与抒情诗  李宏伟</a></li><li><a href="https://book.douban.com/subject/24382569/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  一桩事先张扬的凶杀案  [哥伦比亚] 加西亚·马尔克斯</a></li><li><a href="https://book.douban.com/subject/10555486/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  分成两半的子爵 [意] 伊塔洛·卡尔维诺</a></li><li><a href="https://book.douban.com/subject/27065524/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  美丽新世界 [英] 阿道司·赫胥黎</a></li><li><a href="https://book.douban.com/subject/26937457/" rel="external nofollow noopener noreferrer" target="_blank">2017.06  罗生门 [日] 芥川龙之介</a></li><li><a href="https://book.douban.com/subject/25733470/" rel="external nofollow noopener noreferrer" target="_blank">2017.06  没有色彩的多崎作和他的巡礼之年 [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/5502995/" rel="external nofollow noopener noreferrer" target="_blank">2017.04  1Q84 BOOK 3  [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/26591331/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  你好，旧时光  八月长安</a></li><li><a href="https://book.douban.com/subject/25829434/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  暗恋·橘生淮南  八月长安</a></li><li><a href="https://book.douban.com/subject/24754316/" rel="external nofollow noopener noreferrer" target="_blank">2017.02  最好的我们  八月长安</a></li><li><a href="https://book.douban.com/subject/25905185/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  蝇王  [英] William Golding</a></li><li><a href="https://book.douban.com/subject/4246968/" rel="external nofollow noopener noreferrer" target="_blank">2017.01  局外人  [法] Albert Camus</a></li><li><a href="https://book.douban.com/subject/20443559/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  小王子  [法] 安托万·德·圣埃克苏佩里</a></li><li><a href="https://book.douban.com/subject/26879641/" rel="external nofollow noopener noreferrer" target="_blank">2016.10  套中人  [俄] 契诃夫</a></li><li><a href="https://book.douban.com/subject/4742918/" rel="external nofollow noopener noreferrer" target="_blank">2016.10  1Q84 BOOK 1 [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/4885241/" rel="external nofollow noopener noreferrer" target="_blank">2016.10  1Q84 BOOK 2 [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/26926833/" rel="external nofollow noopener noreferrer" target="_blank">2016.09  动物庄园  [英] George Orwell</a></li><li><a href="https://book.douban.com/subject/26274903/" rel="external nofollow noopener noreferrer" target="_blank">2016.09  麦田里的守望者  [美] J.D.塞林格</a></li><li><a href="https://book.douban.com/subject/25891771/" rel="external nofollow noopener noreferrer" target="_blank">2016.07  失乐园  [日] 渡边淳一</a></li><li><a href="https://book.douban.com/subject/6097966/" rel="external nofollow noopener noreferrer" target="_blank">2016.07  发条橙  [英] Anthony Burgess</a></li><li><a href="https://book.douban.com/subject/25957816/" rel="external nofollow noopener noreferrer" target="_blank">2016.05  悖论13  [日] 东野圭吾</a></li><li><a href="https://book.douban.com/subject/26264953/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  天空之蜂  [日] 东野圭吾</a></li><li><a href="https://book.douban.com/subject/25924253/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  嫌疑人X的献身  [日] 东野圭吾</a></li><li><a href="https://book.douban.com/subject/3673651/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  岛  [英] 维多利亚·希斯洛普</a></li><li><a href="https://book.douban.com/subject/10757939/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  红玫瑰与白玫瑰  张爱玲</a></li><li><a href="https://book.douban.com/subject/25922739/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  十字弓·玫瑰之刃  恒殊</a></li><li><a href="https://book.douban.com/subject/25922740/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  十字弓·背叛者月  恒殊</a></li><li><a href="https://book.douban.com/subject/26261936/" rel="external nofollow noopener noreferrer" target="_blank">2016.04  十字弓·亡者归来  恒殊</a></li><li><a href="https://book.douban.com/subject/26437740/" rel="external nofollow noopener noreferrer" target="_blank">2016.02  梦之海  刘慈欣</a></li><li><a href="https://book.douban.com/subject/2159042/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  挪威的森林  [日] 村上春树</a></li><li><a href="https://book.douban.com/subject/25972529/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  在逃  王若虚</a></li><li><a href="https://book.douban.com/subject/6811711/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  桥声  吴忠全</a></li><li><a href="https://book.douban.com/subject/24540864/" rel="external nofollow noopener noreferrer" target="_blank">2015.03  第七天  余华</a></li><li><a href="https://book.douban.com/subject/25886175/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  星际迷航-红衫  [美] John Scalzi</a></li><li><a href="https://book.douban.com/subject/5275059/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  1988：我想和这个世界谈谈  韩寒</a></li><li><a href="https://book.douban.com/subject/10757940/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  倾城之恋  张爱玲</a></li><li><a href="https://book.douban.com/subject/25900369/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  慢  [法] 米兰·昆德拉</a></li><li><a href="https://book.douban.com/subject/25867688/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  一粒红尘  独木舟</a></li><li><a href="https://book.douban.com/subject/3608208/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  牧羊少年奇幻之旅  [巴西]保罗·柯艾略</a></li><li><a href="https://book.douban.com/subject/25734421/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  胡萝卜须  [法] 儒勒·列那尔</a></li><li><a href="https://book.douban.com/subject/1207513/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  欧叶妮·葛朗台  [法] 巴尔扎克</a></li><li><a href="https://book.douban.com/subject/1087214/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  最后一课  [法] 都德</a></li><li><a href="https://book.douban.com/subject/5922517/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  羊脂球  [法] 莫泊桑</a></li><li><a href="https://book.douban.com/subject/25747921/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  从你的全世界路过  张嘉佳</a></li><li><a href="https://book.douban.com/subject/6781808/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  杀死一只知更鸟  [美] 哈珀·李</a></li><li><a href="https://book.douban.com/subject/1672100/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  神曲  但丁</a></li><li><a href="https://book.douban.com/subject/25798623/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  1984  [英] George Orwell</a></li><li><a href="https://book.douban.com/subject/26385441/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  穹顶之下·危机卷  刘慈欣等</a></li><li><a href="https://book.douban.com/subject/26385442/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  穹顶之下·末日卷  刘慈欣等</a></li><li><a href="https://book.douban.com/subject/6518605/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  三体  刘慈欣</a></li></ul><h2 id="传记"><a class="header-anchor" href="#传记">¶</a>传记</h2><ul><li><a href="https://book.douban.com/subject/26701924/" rel="external nofollow noopener noreferrer" target="_blank">2017.08  特斯拉：电气时代的开创者  [美] W.伯纳德·卡尔森</a></li><li><a href="https://book.douban.com/subject/26759508/" rel="external nofollow noopener noreferrer" target="_blank">2016.12  硅谷钢铁侠  [美] Ashlee Vance</a></li><li><a href="https://book.douban.com/subject/25786645/" rel="external nofollow noopener noreferrer" target="_blank">2015.05  乔纳森传  [美] Leander Kahney</a></li><li><a href="https://book.douban.com/subject/5414530/" rel="external nofollow noopener noreferrer" target="_blank">2015.05  与自己对话  [南非] Nelson Mandela</a></li><li><a href="https://book.douban.com/subject/25806771/" rel="external nofollow noopener noreferrer" target="_blank">2015.01  小QQ大帝国  熊江</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;会频繁持续更新！！！会频繁持续更新！！！会频繁持续更新！！！&lt;br&gt;
也会逐渐补上一些以前看的书，时间记不清那也就随便写啦&lt;br&gt;
格式为：[入手时间] + [书名] + [作者]&lt;br&gt;
点击书名会进入这本书的豆瓣页面&lt;br&gt;
&lt;em&gt;较早期的书本日期统一注为2015.01&lt;/em&gt;&lt;br&gt;
手机党戳右下角的悬浮按钮可以打开目录&lt;/p&gt;
&lt;!--书名前面*越多代表推荐程度越高哦--&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>序  /  INTRO</title>
    <link href="https://leaferx.online/2017/01/16/Hello-World/"/>
    <id>https://leaferx.online/2017/01/16/Hello-World/</id>
    <published>2017-01-16T03:04:00.000Z</published>
    <updated>2019-04-09T07:40:07.439Z</updated>
    
    <content type="html"><![CDATA[<blockquote class="blockquote-center"><p>在现实断裂的地方<br>梦 汇成了海</p><p>顾城 《弥合》</p></blockquote><center>所以你好 欢迎来到 <b>LEAFER x LAB</b><br>这是我的博客 主要写一些技术类的文章<br>当然 可能还会放一些自己的作品<br>那么请持续关注啦<br>比心<img src="https://img.leaferx.ink/6739ea5d0082b2ce8992.jpg" width="100" height="100"></center><a id="more"></a><h3 id="关于我"><a class="header-anchor" href="#关于我">¶</a>关于我</h3><p>咸鱼终于想起来要更新啦哈哈哈哈哈。<br>目前在上海科技大学勤奋<del>睡觉</del>学习.jpg<br><del>咸鱼一只，仍旧挣扎在高考的滚滚浪潮之下，是物竞党 + NOIP蒟蒻。</del><br>喜欢编程，喜欢设计，喜欢尝试各种新奇好玩的东西。<br>喜欢书，喜欢诗和奇奇怪怪的科普。<br>喜欢明信片，喜欢吃。<br>觉得自己应该是一只有趣的咸鱼。</p><h3 id="关于这个博客"><a class="header-anchor" href="#关于这个博客">¶</a>关于这个博客</h3><p>由于各种时间不够，上了大学也只能不定期诈尸 qaq。<br><del>由于各种时间不够，所以大概高考前就都只能不定期诈尸啦。</del><br><img src="https://img.leaferx.ink/16f571ebd405069a1149.jpg" alt="STUDY!!"><br>但是一旦闲下来就会频繁诈尸哦。<br>所以请多多关注啦。</p><h3 id="关于文章转载和其他"><a class="header-anchor" href="#关于文章转载和其他">¶</a>关于文章转载和其他</h3><p>如果没有特殊说明 本站所有文章均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" rel="external nofollow noopener noreferrer" target="_blank">CC BY-NC-SA 4.0 CN</a> 许可协议<br>转载请注明作者并最好附带原文链接哦<br>顺便如果喜欢我的博客 欢迎友链ww</p><h3 id="最后"><a class="header-anchor" href="#最后">¶</a>最后</h3><p>那么，送上一首Alan Pownall的Colourful Day。<br>请多多指教啦w。</p><audio src="https://img.leaferx.ink/051dfd94791c06b66a90.mp3" autoplay controls loop>浏览器不支持audio标签</audio>]]></content>
    
    <summary type="html">
    
      &lt;blockquote class=&quot;blockquote-center&quot;&gt;&lt;p&gt;在现实断裂的地方&lt;br&gt;
梦 汇成了海&lt;/p&gt;
&lt;p&gt;顾城 《弥合》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;center&gt;
所以你好 欢迎来到 &lt;b&gt;LEAFER x LAB&lt;/b&gt;&lt;br&gt;
这是我的博客 主要写一些技术类的文章&lt;br&gt;
当然 可能还会放一些自己的作品&lt;br&gt;
那么请持续关注啦&lt;br&gt;
比心
&lt;img src=&quot;https://img.leaferx.ink/6739ea5d0082b2ce8992.jpg&quot; width=&quot;100&quot; height=&quot;100&quot;&gt;
&lt;/center&gt;
    
    </summary>
    
    
  </entry>
  
</feed>
