aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/posts/2022-04-09
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2023-03-15 01:36:13 +0900
committernsfisis <nsfisis@gmail.com>2023-03-15 01:36:58 +0900
commit98682c7a8792e7e79e487fea5024d25cee5aa310 (patch)
treefbf975077f5c1a6ff4f9eee68e4a4908eb7f54a0 /public/posts/2022-04-09
parent1fa2ed103dc521698cff261c97ecf275708be58c (diff)
downloadblog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.tar.gz
blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.tar.zst
blog.nsfisis.dev-98682c7a8792e7e79e487fea5024d25cee5aa310.zip
fix(nuldoc): <pre> contained unnecessary whitespaces inside it
Diffstat (limited to 'public/posts/2022-04-09')
-rw-r--r--public/posts/2022-04-09/phperkaigi-2022-tokens/index.html76
1 files changed, 23 insertions, 53 deletions
diff --git a/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html b/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
index d16739b..bbeacb2 100644
--- a/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
+++ b/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
@@ -66,8 +66,7 @@
ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>&lt;?php
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>&lt;?php
declare(strict_types=0O1);
@@ -135,8 +134,7 @@
$👉, $👍, $👍, $📝,
$👉, $👎, $📝,
$👈, $📝,
- ]);</code>
- </pre>
+ ]);</code></pre>
<p>
この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。
@@ -165,8 +163,7 @@
なお、brainf*ck プログラムを普通の書き方で書くと、次のようになる。
</p>
- <pre class="monospaced highlight">
- <code>+ + + + + + + + + +
+ <pre class="monospaced highlight"><code>+ + + + + + + + + +
[
&gt; + + +
&gt; + + + + +
@@ -187,8 +184,7 @@
&lt; .
&gt; + + .
&gt; - .
-&lt; .</code>
- </pre>
+&lt; .</code></pre>
<p>
実行結果はこちら:<a href="https://ideone.com/22VWmb">https://ideone.com/22VWmb</a>
@@ -271,9 +267,7 @@
ソースコードのライセンスを示したこの部分だが、
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>https://creativecommons.org/publicdomain/zero/1.0/</code>
- </pre>
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>https://creativecommons.org/publicdomain/zero/1.0/</code></pre>
<p>
完全に合法な PHP のコードである。<code>https:</code>部分はラベル、<code>//</code>以降は行コメントになっている。
@@ -286,13 +280,11 @@
ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。 PHP では、型変換を利用することで任意の整数を作り出すことができる。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>assert(0 === +!![]);
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>assert(0 === +!![]);
assert(1 === +![]);
assert(2 === ![]+![]);
assert(3 === ![]+![]+![]);
-assert(10 === +(![].+!![]));</code>
- </pre>
+assert(10 === +(![].+!![]));</code></pre>
<p>
<code>[]</code>に<code>!</code>を適用すると<code>true</code>が返ってくる。それに<code>+</code>を適用すると、<code>bool</code>から<code>int</code>ヘの型変換が走り、<code>1</code>が生成される。<code>10</code>はさらにトリッキーだ。まず<code>1</code>と<code>0</code>を作り、<code>.</code>で文字列として結合する (<code>&apos;10&apos;</code>)。これに<code>+</code>を適用すると、<code>string</code>から<code>int</code>への型変換が走り、<code>10</code>が生まれる (コード量に頓着しないなら、<code>1</code>を 10 個足し合わせてももちろん 10 が作れる)。
@@ -333,8 +325,7 @@ assert(10 === +(![].+!![]));</code>
ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>&lt;?php
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>&lt;?php
/*********************************************************
* This program displays a PHPer token. *
@@ -367,8 +358,7 @@ assert(10 === +(![].+!![]));</code>
$x = str_replace(search: [&apos;0&apos;, &apos;1&apos;], replace: [&apos; &apos;, &apos;#&apos;], subject: $x);
$x = implode(&quot;\n&quot;, str_split($x, length: 5));
echo &quot;{$x}\n\n&quot;;
- }</code>
- </pre>
+ }</code></pre>
<p>
さて、この問題はさきほどのように単純に実行しただけでは、謎のブロックが表示されるだけでトークンは得られない。 トークンを得るためには、ソースコードを読み、定数<code>N</code>を特定する必要がある。
@@ -384,43 +374,33 @@ assert(10 === +(![].+!![]));</code>
まずはソースコードを読んでいく。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>$token = [
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>$token = [
// 略
- ];</code>
- </pre>
+ ];</code></pre>
<p>
数値からなる<code>$token</code>があり、各要素をループしている。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code> $x = $x ^ N;</code>
- </pre>
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = $x ^ N;</code></pre>
<p>
まずは排他的論理和 (xor) を取り、
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code> $x = sprintf(&apos;%025b&apos;, $x);</code>
- </pre>
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = sprintf(&apos;%025b&apos;, $x);</code></pre>
<p>
二進数に変換して、
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code> $x = str_replace(search: [&apos;0&apos;, &apos;1&apos;], replace: [&apos; &apos;, &apos;#&apos;], subject: $x);</code>
- </pre>
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = str_replace(search: [&apos;0&apos;, &apos;1&apos;], replace: [&apos; &apos;, &apos;#&apos;], subject: $x);</code></pre>
<p>
0 を空白に、1 を<code>#</code>にし、
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code> $x = implode(&quot;\n&quot;, str_split($x, length: 5));</code>
- </pre>
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = implode(&quot;\n&quot;, str_split($x, length: 5));</code></pre>
<p>
5文字ごとに区切ったあと、改行で結合している。
@@ -474,16 +454,13 @@ assert(10 === +(![].+!![]));</code>
<code>N</code>は高々
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>assert(0 &lt;= N &amp;&amp; N &lt;= 0b11111_11111_11111_11111_11111);</code>
- </pre>
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>assert(0 &lt;= N &amp;&amp; N &lt;= 0b11111_11111_11111_11111_11111);</code></pre>
<p>
なのでブルートフォースしてもよいが、ここではブルートフォースしない方法を紹介する。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>&lt;?php
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>&lt;?php
$x = 0x14B499C;
@@ -498,15 +475,13 @@ assert(10 === +(![].+!![]));</code>
&quot;#####\n&quot; .
&quot; # # \n&quot; .
&quot;#####\n&quot; .
- &quot; # # &quot;);</code>
- </pre>
+ &quot; # # &quot;);</code></pre>
<p>
この一連の変換に対する逆変換を考えると、次のようになる。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>&lt;?php
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>&lt;?php
$x =
&quot; # # \n&quot; .
@@ -521,8 +496,7 @@ $x = bindec($x);
$n = $x ^ 0x14B499C;
-echo &quot;N = $n\n&quot;;</code>
- </pre>
+echo &quot;N = $n\n&quot;;</code></pre>
<p>
これを実行すると、<code>N</code>が得られる。
@@ -536,8 +510,7 @@ echo &quot;N = $n\n&quot;;</code>
ソースコードはこちら。
</p>
- <pre class="highlight" language="php" linenumbering="unnumbered">
- <code>&lt;?php
+ <pre class="highlight" language="php" linenumbering="unnumbered"><code>&lt;?php
// License: https://creativecommons.org/publicdomain/zero/1.0/
// This is a quine-like program to generate a PHPer token.
@@ -565,16 +538,13 @@ echo &quot;N = $n\n&quot;;</code>
$t = null.false; for ($i = 0; $i &lt;= intdiv(__LINE__-035,6); ++$i) if (!isset($xs[$i])) break; else
$t .= implode(&quot;\n&quot;, str_split(str_replace([&apos;0&apos;,&apos;1&apos;], [&apos; &apos;,&apos;##&apos;], sprintf(chr(37) . &apos;025b&apos;, $xs[$i])), 012)) . &quot;\n\n&quot;;
$ws = array_map(fn($w) =&gt; implode(&apos;, &apos;, $w), array_chunk(array_map(fn($x) =&gt; sprintf(&apos;0x&apos; . chr(37) . &apos;07X&apos;, $x), $xs), 10));
- printf($s, $t, str_rot13(&quot;&lt;&lt;&lt;&apos;D&apos;\n{$s}\nD&quot;), implode(&quot;,\n&quot;, $ws));</code>
- </pre>
+ printf($s, $t, str_rot13(&quot;&lt;&lt;&lt;&apos;D&apos;\n{$s}\nD&quot;), implode(&quot;,\n&quot;, $ws));</code></pre>
<p>
コメントにもあるとおり、次のようにして実行すれば答えがでてくる。
</p>
- <pre class="highlight" language="shell-session" linenumbering="unnumbered">
- <code>$ php toquine.php | php | php | php | ...</code>
- </pre>
+ <pre class="highlight" language="shell-session" linenumbering="unnumbered"><code>$ php toquine.php | php | php | php | ...</code></pre>
<p>
実際にはもう少しパイプで繋げなければならない。