aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/posts/2022-11-19/phperkaigi-2023-unused-token-quiz-2/index.html
blob: e785f4f66a4bca511051cb7409e35fb482549401 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
<!DOCTYPE html>
<html lang="ja-JP">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="author" content="nsfisis">
    <meta name="copyright" content="&copy; 2022 nsfisis">
    <meta name="description" content="来年の PHPerKaigi 2023 でデジタルサーカス株式会社から出題予定のトークン問題のうち、ボツになった問題を公開する (その 2)。">
    <meta name="keywords" content="PHP,PHPerKaigi">
    <link rel="icon" type="image/svg+xml" href="/favicon.svg">
    <title>PHPerKaigi 2023: ボツになったトークン問題 その 2 | REPL: Rest-Eat-Program Loop</title>
    <link rel="stylesheet" href="/hl.css?h=208c52e3b7c9db1cad782c5d30b4698f">
    <link rel="stylesheet" href="/style.css?h=779b1a3debcaeba619f6fe500e93d525">
    <link rel="stylesheet" href="/custom.css?h=a649ea3528d4b626fb636505d94c1144">
  </head>
  <body class="single">
    <header class="header">
      <nav class="nav">
        <p class="logo">
          <a href="/">REPL: Rest-Eat-Program Loop</a>
        </p>
      </nav>
    </header>
    <main class="main">
      <article class="post-single">
        <header class="post-header">
          <h1 class="post-title">PHPerKaigi 2023: ボツになったトークン問題 その 2</h1>
          <ul class="post-tags">
            <li class="tag">
              <a href="/tags/php">PHP</a>
            </li>
            <li class="tag">
              <a href="/tags/phperkaigi">PHPerKaigi</a>
            </li>
          </ul>
        </header>
        <div class="post-content">
          <section>
            <h2 id="changelog">更新履歴</h2>
            <ol>
              <li class="revision">
                <time datetime="2022-11-19">2022-11-19</time>: 公開
              </li>
            </ol>
          </section>
          <section id="section--_はじめに">
            <h2><a href="#section--_はじめに">はじめに</a></h2>
            <p>
              2023 年 3 月 23 日から 25 日にかけて開催予定 (記事執筆時点) の<a xl:href="https://phperkaigi.jp/2023/">PHPerKaigi 2023</a>において、 昨年と同様に、弊社<a xl:href="https://www.dgcircus.com/">デジタルサーカス株式会社</a>からトークン問題を出題予定である。
            </p>
            
            <p>
              昨年のトークン問題の記事はこちら:<a xl:href="/posts/2022-04-09/phperkaigi-2022-tokens/">PHPerKaigi 2022 トークン問題の解説</a>
            </p>
            
            <p>
              すでに 2023 年用の問題は作成済みであるが、その制作過程の中でいくつかボツ問ができた。せっかくなので、PHPerKaigi 開催を待つ間に紹介しようと思う。
            </p>
            
            <p>
              10 月から 2 月まで、毎月 1 記事ずつ公開していく予定 (忘れていなければ)。
            </p>
            
            <p>
              その 1 はこちら:<a xl:href="/posts/2022-10-23/phperkaigi-2023-unused-token-quiz-1/">PHPerKaigi 2023: ボツになったトークン問題 その 1</a>
            </p>
          </section>
          
          <section id="section--_問題">
            <h2><a href="#section--_問題">問題</a></h2>
            <p>
              注意: これはボツ問なので、得られたトークンを PHPerKaigi で入力してもポイントにはならない。
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;</code>
            </pre>
            
            <p>
              &quot;And Then There Were None&quot; (そして誰もいなくなった) と名付けた作品。変則 quine (自分自身と同じソースコードを出力するプログラム) になっている。
            </p>
          </section>
          
          <section id="section--_トークン入手方法">
            <h2><a href="#section--_トークン入手方法">トークン入手方法</a></h2>
            <p>
              実行してみると、次のような出力が得られる。
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>#
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
  &lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;</code>
            </pre>
            
            <p>
              1 行目を除き、先ほどのコードとほぼ同じものが出てきた。もう一度実行してみる。
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>#
W
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;
&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;​&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;</code>
            </pre>
            
            <p>
              今度は 2 行目が書き換えられた。すべての行が変化するまで繰り返すと次のようになる。
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>#
W
E
L
O
V
E
P
H
P</code>
            </pre>
            
            <p>
              トークン「#WELOVEPHP」が手に入った。
            </p>
          </section>
          
          <section id="section--_解説">
            <h2><a href="#section--_解説">解説</a></h2>
            <p>
              一見すると同じ行が 10 行並んでいるだけなのにも関わらず、なぜそれぞれの行で出力が変わるのか。ソースコードをコピーして、適当なエディタに貼り付けるとわかりやすい。
            </p>
            
            <p>
              Vim で開くと次のようになる (1 行目を抜粋)。
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;&lt;200b&gt;&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=&apos;&lt;200b&gt;&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;&lt;200b&gt;&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;</code>
            </pre>
            
            <p>
              <code>&lt;200b&gt;</code>と表示されているのは、Unicode の U+200b で、ゼロ幅スペースである。
            </p>
            
            <div>
              <div>
                Note
              </div>
              <div>
                <p>
                  エディタによっては、ゼロ幅スペースが見えないことがある。VSCode ではブラウザと同様に不可視だった。
                </p>
              </div>
            </div>
            
            <p>
              文字列リテラルの中にゼロ幅スペースを仕込むことで、見た目を変えずに情報をエンコードすることが可能となる。
            </p>
            
            <p>
              続いて、トークンへの変換ロジックを解析する。注目すべきはこの部分だ。以下、ゼロ幅スペースは Vim での表示に合わせて<code>&lt;200b&gt;</code>と記載する。
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>fn($s)=&gt;chr(strlen($s)/3)</code>
            </pre>
            
            <p>
              PHP の<code>strlen()</code>は文字列のバイト数を返す。1 行目の<code>$s</code>は以下の内容となっており、
            </p>
            
            <pre language="php" linenumbering="unnumbered">
              <code>$s=&apos;&lt;200b&gt;&lt;?php printf((isset($s)?fn($s)=&gt;trim($s,&quot;&lt;200b&gt;&quot;):fn($s)=&gt;chr(strlen($s)/3))($s=%s).&quot;\n&quot;,&quot;\x27$s\x27&quot;);?&gt;&apos;</code>
            </pre>
            
            <p>
              このソースコードは UTF-8 で書かれているので、105 バイトになる。それを 3 で割ると 35 となり、これは<code>#</code>の ASCII コードと一致する。他の行も、同様にしてゼロ幅スペースを詰めることで文字列長を調整し、トークンをエンコードしている。
            </p>
            
            <p>
              デコード部以外の部分は、quine のための記述である。
            </p>
          </section>
          
          <section id="section--_おわりに">
            <h2><a href="#section--_おわりに">おわりに</a></h2>
            <p>
              <a xl:href="https://blog.rust-lang.org/2021/11/01/cve-2021-42574.html">CVE-2021-42574</a>に着想を得た作品。この脆弱性は、Unicode の制御文字である left-to-right mark と right-to-left mark を利用し、ソースコードの実際の内容を欺く、というもの。簡単のためゼロ幅スペースを用いることとし、ついでに quine にもするとこうなった。
            </p>
            
            <p>
              ボツになった理由は、ゼロ幅スペースを表示してくるエディタが想像以上に多かったため。「同じ行が並んでいるだけなのに出力が異なる」というアイデアの根幹を崩されてしまうので、この問題は不採用となった。
            </p>
          </section>
        </div>
      </article>
    </main>
    <footer class="footer">
      &copy; 2021 nsfisis
    </footer>
  </body>
</html>