diff options
Diffstat (limited to 'public/posts/2022-04-09')
| -rw-r--r-- | public/posts/2022-04-09/phperkaigi-2022-tokens/index.html | 258 |
1 files changed, 129 insertions, 129 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 9ac3f90..25873b7 100644 --- a/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html +++ b/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html @@ -10,7 +10,7 @@ <link rel="icon" type="image/svg+xml" href="/favicon.svg"> <title>PHPerKaigi 2022 トークン問題の解説 | REPL: Rest-Eat-Program Loop</title> <link rel="stylesheet" href="/style.css?h=17cf97a767ec5fb6e64967729f40f30a"> - <link rel="stylesheet" href="/hl.css?h=208c52e3b7c9db1cad782c5d30b4698f"> + <link rel="stylesheet" href="/hl.css?h=340e65ffd5c17713efc9107c06304f7b"> </head> <body class="single"> <header class="header"> @@ -76,50 +76,50 @@ ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> - declare(strict_types=0O1); + <span class="hljs-keyword">declare</span>(strict_types=<span class="hljs-number">0O1</span>); - namespace Dgcircus\PHPerKaigi\Y2022; + <span class="hljs-keyword">namespace</span> <span class="hljs-title class_">Dgcircus</span>\<span class="hljs-title class_">PHPerKaigi</span>\<span class="hljs-title class_">Y2022</span>; - /** - * @todo + <span class="hljs-comment">/** + * <span class="hljs-doctag">@todo</span> * Run this program to acquire a PHPer token. - */ + */</span> - https://creativecommons.org/publicdomain/zero/1.0/ + https:<span class="hljs-comment">//creativecommons.org/publicdomain/zero/1.0/</span> - \error_reporting(~+!'We are hiring!'); + \<span class="hljs-title function_ invoke__">error_reporting</span>(~+!<span class="hljs-string">'We are hiring!'</span>); - $z = fn($f) => (fn($x) => $f(fn(...$xs) => $x($x)(...$xs)))(fn($x) => $f(fn(...$xs) => $x($x)(...$xs))); - $id = \spl_object_id(...); - $put = fn($c) => \printf('%c', $c); - $mm = fn($p, $n) => new \ArrayObject(\array_fill(+!![], $n, $p)); + <span class="hljs-variable">$z</span> = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$f</span></span>) =></span> (<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$x</span></span>) =></span> <span class="hljs-variable">$f</span>(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params">...<span class="hljs-variable">$xs</span></span>) =></span> <span class="hljs-variable">$x</span>(<span class="hljs-variable">$x</span>)(...<span class="hljs-variable">$xs</span>)))(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$x</span></span>) =></span> <span class="hljs-variable">$f</span>(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params">...<span class="hljs-variable">$xs</span></span>) =></span> <span class="hljs-variable">$x</span>(<span class="hljs-variable">$x</span>)(...<span class="hljs-variable">$xs</span>))); + <span class="hljs-variable">$id</span> = \<span class="hljs-title function_ invoke__">spl_object_id</span>(...); + <span class="hljs-variable">$put</span> = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$c</span></span>) =></span> \<span class="hljs-title function_ invoke__">printf</span>(<span class="hljs-string">'%c'</span>, <span class="hljs-variable">$c</span>); + <span class="hljs-variable">$mm</span> = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$p</span>, <span class="hljs-variable">$n</span></span>) =></span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">\ArrayObject</span>(\<span class="hljs-title function_ invoke__">array_fill</span>(+!![], <span class="hljs-variable">$n</span>, <span class="hljs-variable">$p</span>)); - $👉 = fn($m, $p, $b, $e, $mp, $pc) => [++$mp, ++$pc]; - $👈 = fn($m, $p, $b, $e, $mp, $pc) => [--$mp, ++$pc]; - $👍 = fn($m, $p, $b, $e, $mp, $pc) => [$mp, ++$pc, ++$m[$mp]]; - $👎 = fn($m, $p, $b, $e, $mp, $pc) => [$mp, ++$pc, --$m[$mp]]; - $📝 = fn($m, $p, $b, $e, $mp, $pc) => [$mp, ++$pc, $put($m[$mp])]; - $🤡 = fn($m, $p, $b, $e, $mp, $pc) => match ($m[$mp]) { - +!![] => [$mp, $z(fn($loop) => fn($pc, $n) => match ($id($p[$pc])) { - $b => $loop(++$pc, ++$n), - $e => $n === +!![] ? ++$pc : $loop(++$pc, --$n), - default => $loop(++$pc, $n), - })($pc, -![])], - default => [$mp, ++$pc], + $👉 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> [++<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>]; + $👈 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> [--<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>]; + $👍 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> [<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>, ++<span class="hljs-variable">$m</span>[<span class="hljs-variable">$mp</span>]]; + $👎 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> [<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>, --<span class="hljs-variable">$m</span>[<span class="hljs-variable">$mp</span>]]; + $📝 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> [<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>, <span class="hljs-variable">$put</span>(<span class="hljs-variable">$m</span>[<span class="hljs-variable">$mp</span>])]; + $🤡 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> <span class="hljs-keyword">match</span> (<span class="hljs-variable">$m</span>[<span class="hljs-variable">$mp</span>]) { + +!![] => [<span class="hljs-variable">$mp</span>, <span class="hljs-variable">$z</span>(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$loop</span></span>) =></span> <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$pc</span>, <span class="hljs-variable">$n</span></span>) =></span> <span class="hljs-keyword">match</span> (<span class="hljs-variable">$id</span>(<span class="hljs-variable">$p</span>[<span class="hljs-variable">$pc</span>])) { + <span class="hljs-variable">$b</span> => <span class="hljs-variable">$loop</span>(++<span class="hljs-variable">$pc</span>, ++<span class="hljs-variable">$n</span>), + <span class="hljs-variable">$e</span> => <span class="hljs-variable">$n</span> === +!![] ? ++<span class="hljs-variable">$pc</span> : <span class="hljs-variable">$loop</span>(++<span class="hljs-variable">$pc</span>, --<span class="hljs-variable">$n</span>), + <span class="hljs-keyword">default</span> => <span class="hljs-variable">$loop</span>(++<span class="hljs-variable">$pc</span>, <span class="hljs-variable">$n</span>), + })(<span class="hljs-variable">$pc</span>, -![])], + <span class="hljs-keyword">default</span> => [<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>], }; - $🎪 = fn($m, $p, $b, $e, $mp, $pc) => match ($m[$mp]) { - +!![] => [$mp, ++$pc], - default => [$mp, $z(fn($loop) => fn($pc, $n) => match ($id($p[$pc])) { - $e => $loop(--$pc, ++$n), - $b => $n === +!![] ? $pc+![] : $loop(--$pc, --$n), - default => $loop(--$pc, $n), - })($pc, -![])], + $🎪 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> <span class="hljs-keyword">match</span> (<span class="hljs-variable">$m</span>[<span class="hljs-variable">$mp</span>]) { + +!![] => [<span class="hljs-variable">$mp</span>, ++<span class="hljs-variable">$pc</span>], + <span class="hljs-keyword">default</span> => [<span class="hljs-variable">$mp</span>, <span class="hljs-variable">$z</span>(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$loop</span></span>) =></span> <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$pc</span>, <span class="hljs-variable">$n</span></span>) =></span> <span class="hljs-keyword">match</span> (<span class="hljs-variable">$id</span>(<span class="hljs-variable">$p</span>[<span class="hljs-variable">$pc</span>])) { + <span class="hljs-variable">$e</span> => <span class="hljs-variable">$loop</span>(--<span class="hljs-variable">$pc</span>, ++<span class="hljs-variable">$n</span>), + <span class="hljs-variable">$b</span> => <span class="hljs-variable">$n</span> === +!![] ? <span class="hljs-variable">$pc</span>+![] : <span class="hljs-variable">$loop</span>(--<span class="hljs-variable">$pc</span>, --<span class="hljs-variable">$n</span>), + <span class="hljs-keyword">default</span> => <span class="hljs-variable">$loop</span>(--<span class="hljs-variable">$pc</span>, <span class="hljs-variable">$n</span>), + })(<span class="hljs-variable">$pc</span>, -![])], }; - $🐘 = fn($p) => $z(fn($loop) => fn($m, $p, $b, $e, $mp, $pc) => - isset($p[$pc]) && $loop($m, $p, $b, $e, ...($p[$pc]($m, $p, $b, $e, $mp, $pc))) - )($mm(+!![], +(![].![])), $p, $id($🤡), $id($🎪), +!![], +!![]); + $🐘 = <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$p</span></span>) =></span> <span class="hljs-variable">$z</span>(<span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$loop</span></span>) =></span> <span class="hljs-function"><span class="hljs-keyword">fn</span>(<span class="hljs-params"><span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span></span>) =></span> + <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$p</span>[<span class="hljs-variable">$pc</span>]) && <span class="hljs-variable">$loop</span>(<span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, ...(<span class="hljs-variable">$p</span>[<span class="hljs-variable">$pc</span>](<span class="hljs-variable">$m</span>, <span class="hljs-variable">$p</span>, <span class="hljs-variable">$b</span>, <span class="hljs-variable">$e</span>, <span class="hljs-variable">$mp</span>, <span class="hljs-variable">$pc</span>))) + )(<span class="hljs-variable">$mm</span>(+!![], +(![].![])), <span class="hljs-variable">$p</span>, <span class="hljs-variable">$id</span>($🤡), <span class="hljs-variable">$id</span>($🎪), +!![], +!![]); $🐘([ $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, @@ -175,26 +175,26 @@ <pre class="monospaced highlight"><code>+ + + + + + + + + + [ -> + + + -> + + + + + -> + + + + + + + + + + + + -> + + + + + + + + + + -< < < < - +> + + + +> + + + + + +> + + + + + + + + + + + + +> + + + + + + + + + + +< < < < - ] -> + + + + + . +> + + + + + . - - . -> - - - . -> - - - . +> - - - . +> - - - . - - . - . -< . -> > - - . +< . +> > - - . + + + + + + + . -< - - - - . -< . -> + + . -> - . -< .</code></pre> +< - - - - . +< . +> + + . +> - . +< .</code></pre> <p> 実行結果はこちら:<a href="https://ideone.com/22VWmb">https://ideone.com/22VWmb</a> @@ -277,7 +277,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 class="highlight">https:<span class="hljs-comment">//creativecommons.org/publicdomain/zero/1.0/</span></code></pre> <p> 完全に合法な PHP のコードである。<code>https:</code>部分はラベル、<code>//</code>以降は行コメントになっている。 @@ -290,11 +290,11 @@ ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。 PHP では、型変換を利用することで任意の整数を作り出すことができる。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code>assert(0 === +!![]); -assert(1 === +![]); -assert(2 === ![]+![]); -assert(3 === ![]+![]+![]); -assert(10 === +(![].+!![]));</code></pre> + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">0</span> === +!![]); +<span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">1</span> === +![]); +<span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">2</span> === ![]+![]); +<span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">3</span> === ![]+![]+![]); +<span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">10</span> === +(![].+!![]));</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>'10'</code>)。これに<code>+</code>を適用すると、<code>string</code>から<code>int</code>への型変換が走り、<code>10</code>が生まれる (コード量に頓着しないなら、<code>1</code>を 10 個足し合わせてももちろん 10 が作れる)。 @@ -335,11 +335,11 @@ assert(10 === +(![].+!![]));</code></pre> ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> - /********************************************************* + <span class="hljs-comment">/********************************************************* * This program displays a PHPer token. * - * Guess 'N'. * + * Guess 'N'. * * * * Hints: * * - N itself has no special meaning, e.g., 42, 8128, * @@ -350,24 +350,24 @@ assert(10 === +(![].+!![]));</code></pre> * * * License: * * https://creativecommons.org/publicdomain/zero/1.0/ * - *********************************************************/ - const N = 0 /* Change it to your answer. */; - assert(0 <= N && N <= 0b11111_11111_11111_11111_11111); + *********************************************************/</span> + <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">N</span> = <span class="hljs-number">0</span> <span class="hljs-comment">/* Change it to your answer. */</span>; + <span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">0</span> <= N && N <= <span class="hljs-number">0b11111_11111_11111_11111_11111</span>); - $token = [ - 0x14B499C, - 0x0BE34CC, 0x01C9C69, - 0x0ECA069, 0x01C2449, 0x0FDB166, 0x01C9C69, - 0x01C1C66, 0x0FC1C47, 0x01C1C66, - 0x10C5858, 0x1E4E3B8, 0x1A2F2F8, + <span class="hljs-variable">$token</span> = [ + <span class="hljs-number">0x14B499C</span>, + <span class="hljs-number">0x0BE34CC</span>, <span class="hljs-number">0x01C9C69</span>, + <span class="hljs-number">0x0ECA069</span>, <span class="hljs-number">0x01C2449</span>, <span class="hljs-number">0x0FDB166</span>, <span class="hljs-number">0x01C9C69</span>, + <span class="hljs-number">0x01C1C66</span>, <span class="hljs-number">0x0FC1C47</span>, <span class="hljs-number">0x01C1C66</span>, + <span class="hljs-number">0x10C5858</span>, <span class="hljs-number">0x1E4E3B8</span>, <span class="hljs-number">0x1A2F2F8</span>, ]; - foreach ($token as $x) { - $x = $x ^ N; + <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$token</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$x</span>) { + <span class="hljs-variable">$x</span> = <span class="hljs-variable">$x</span> ^ N; - $x = sprintf('%025b', $x); - $x = str_replace(search: ['0', '1'], replace: [' ', '#'], subject: $x); - $x = implode("\n", str_split($x, length: 5)); - echo "{$x}\n\n"; + <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-string">'%025b'</span>, <span class="hljs-variable">$x</span>); + <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-attr">search</span>: [<span class="hljs-string">'0'</span>, <span class="hljs-string">'1'</span>], <span class="hljs-attr">replace</span>: [<span class="hljs-string">' '</span>, <span class="hljs-string">'#'</span>], <span class="hljs-attr">subject</span>: <span class="hljs-variable">$x</span>); + <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-variable">$x</span>, <span class="hljs-attr">length</span>: <span class="hljs-number">5</span>)); + <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">{$x}</span>\n\n"</span>; }</code></pre> <p> @@ -384,33 +384,33 @@ assert(10 === +(![].+!![]));</code></pre> まずはソースコードを読んでいく。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code>$token = [ - // 略 + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-variable">$token</span> = [ + <span class="hljs-comment">// 略</span> ];</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 class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-variable">$x</span> ^ N;</code></pre> <p> まずは排他的論理和 (xor) を取り、 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = sprintf('%025b', $x);</code></pre> + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-string">'%025b'</span>, <span class="hljs-variable">$x</span>);</code></pre> <p> 二進数に変換して、 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = str_replace(search: ['0', '1'], replace: [' ', '#'], subject: $x);</code></pre> + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-attr">search</span>: [<span class="hljs-string">'0'</span>, <span class="hljs-string">'1'</span>], <span class="hljs-attr">replace</span>: [<span class="hljs-string">' '</span>, <span class="hljs-string">'#'</span>], <span class="hljs-attr">subject</span>: <span class="hljs-variable">$x</span>);</code></pre> <p> 0 を空白に、1 を<code>#</code>にし、 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code> $x = implode("\n", str_split($x, length: 5));</code></pre> + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-variable">$x</span>, <span class="hljs-attr">length</span>: <span class="hljs-number">5</span>));</code></pre> <p> 5文字ごとに区切ったあと、改行で結合している。 @@ -464,49 +464,49 @@ assert(10 === +(![].+!![]));</code></pre> <code>N</code>は高々 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code>assert(0 <= N && N <= 0b11111_11111_11111_11111_11111);</code></pre> + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">0</span> <= N && N <= <span class="hljs-number">0b11111_11111_11111_11111_11111</span>);</code></pre> <p> なのでブルートフォースしてもよいが、ここではブルートフォースしない方法を紹介する。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> - $x = 0x14B499C; + <span class="hljs-variable">$x</span> = <span class="hljs-number">0x14B499C</span>; - $x = $x ^ N; + <span class="hljs-variable">$x</span> = <span class="hljs-variable">$x</span> ^ N; - $x = sprintf('%025b', $x); - $x = str_replace(search: ['0', '1'], replace: [' ', '#'], subject: $x); - $x = implode("\n", str_split($x, length: 5)); + <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-string">'%025b'</span>, <span class="hljs-variable">$x</span>); + <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-attr">search</span>: [<span class="hljs-string">'0'</span>, <span class="hljs-string">'1'</span>], <span class="hljs-attr">replace</span>: [<span class="hljs-string">' '</span>, <span class="hljs-string">'#'</span>], <span class="hljs-attr">subject</span>: <span class="hljs-variable">$x</span>); + <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-variable">$x</span>, <span class="hljs-attr">length</span>: <span class="hljs-number">5</span>)); - assert($x === - " # # \n" . - "#####\n" . - " # # \n" . - "#####\n" . - " # # ");</code></pre> + <span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-variable">$x</span> === + <span class="hljs-string">" # # \n"</span> . + <span class="hljs-string">"#####\n"</span> . + <span class="hljs-string">" # # \n"</span> . + <span class="hljs-string">"#####\n"</span> . + <span class="hljs-string">" # # "</span>);</code></pre> <p> この一連の変換に対する逆変換を考えると、次のようになる。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> -$x = -" # # \n" . -"#####\n" . -" # # \n" . -"#####\n" . -" # # "; +<span class="hljs-variable">$x</span> = +<span class="hljs-string">" # # \n"</span> . +<span class="hljs-string">"#####\n"</span> . +<span class="hljs-string">" # # \n"</span> . +<span class="hljs-string">"#####\n"</span> . +<span class="hljs-string">" # # "</span>; -$x = implode('', explode("\n", $x)); -$x = str_replace(search: [' ', '#'], replace: ['0', '1'], subject: $x); -$x = bindec($x); +<span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">''</span>, <span class="hljs-title function_ invoke__">explode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-variable">$x</span>)); +<span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-attr">search</span>: [<span class="hljs-string">' '</span>, <span class="hljs-string">'#'</span>], <span class="hljs-attr">replace</span>: [<span class="hljs-string">'0'</span>, <span class="hljs-string">'1'</span>], <span class="hljs-attr">subject</span>: <span class="hljs-variable">$x</span>); +<span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">bindec</span>(<span class="hljs-variable">$x</span>); -$n = $x ^ 0x14B499C; +<span class="hljs-variable">$n</span> = <span class="hljs-variable">$x</span> ^ <span class="hljs-number">0x14B499C</span>; -echo "N = $n\n";</code></pre> +<span class="hljs-keyword">echo</span> <span class="hljs-string">"N = <span class="hljs-subst">$n</span>\n"</span>;</code></pre> <p> これを実行すると、<code>N</code>が得られる。 @@ -520,41 +520,41 @@ echo "N = $n\n";</code></pre> ソースコードはこちら。 </p> - <pre class="highlight" language="php" linenumbering="unnumbered"><code><?php + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> - // License: https://creativecommons.org/publicdomain/zero/1.0/ - // This is a quine-like program to generate a PHPer token. - // Execute it like this: php toquine.php | php | php | php | ... + <span class="hljs-comment">// License: https://creativecommons.org/publicdomain/zero/1.0/</span> + <span class="hljs-comment">// This is a quine-like program to generate a PHPer token.</span> + <span class="hljs-comment">// Execute it like this: php toquine.php | php | php | php | ...</span> - $s = <<<'Q' - <?cuc - // Yvprafr: uggcf://perngvirpbzzbaf.bet/choyvpqbznva/mreb/1.0/ - // Guvf vf n dhvar-yvxr cebtenz gb trarengr n CUCre gbxra. - // Rkrphgr vg yvxr guvf: cuc gbdhvar.cuc | cuc | cuc | cuc | ... - %f$f = %f; - $f = fge_ebg13($f); $kf = [ + <span class="hljs-variable">$s</span> = <<<<span class="hljs-string">'Q'</span> + <span class="hljs-meta"><?</span>cuc + <span class="hljs-comment">// Yvprafr: uggcf://perngvirpbzzbaf.bet/choyvpqbznva/mreb/1.0/</span> + <span class="hljs-comment">// Guvf vf n dhvar-yvxr cebtenz gb trarengr n CUCre gbxra.</span> + <span class="hljs-comment">// Rkrphgr vg yvxr guvf: cuc gbdhvar.cuc | cuc | cuc | cuc | ...</span> + %f<span class="hljs-variable">$f</span> = %f; + <span class="hljs-variable">$f</span> = <span class="hljs-title function_ invoke__">fge_ebg13</span>(<span class="hljs-variable">$f</span>); <span class="hljs-variable">$kf</span> = [ %f, ]; - $g = ahyy.snyfr; sbe ($v = 0; $v <= vagqvi(__YVAR__-035,6); ++$v) vs (!vffrg($kf[$v])) oernx; ryfr - $g .= vzcybqr("\a", fge_fcyvg(fge_ercynpr(['0','1'], [' ','##'], fcevags(pue(37) . '025o', $kf[$v])), 012)) . "\a\a"; - $jf = neenl_znc(sa($j) => vzcybqr(', ', $j), neenl_puhax(neenl_znc(sa($k) => fcevags('0k' . pue(37) . '07K', $k), $kf), 10)); - cevags($f, $g, fge_ebg13("<<<'Q'\a{$f}\aQ"), vzcybqr(",\a", $jf)); + <span class="hljs-variable">$g</span> = ahyy.snyfr; <span class="hljs-title function_ invoke__">sbe</span> (<span class="hljs-variable">$v</span> = <span class="hljs-number">0</span>; <span class="hljs-variable">$v</span> <= <span class="hljs-title function_ invoke__">vagqvi</span>(__YVAR__-<span class="hljs-number">035</span>,<span class="hljs-number">6</span>); ++<span class="hljs-variable">$v</span>) <span class="hljs-title function_ invoke__">vs</span> (!<span class="hljs-title function_ invoke__">vffrg</span>(<span class="hljs-variable">$kf</span>[<span class="hljs-variable">$v</span>])) oernx; ryfr + <span class="hljs-variable">$g</span> .= <span class="hljs-title function_ invoke__">vzcybqr</span>(<span class="hljs-string">"\a"</span>, <span class="hljs-title function_ invoke__">fge_fcyvg</span>(<span class="hljs-title function_ invoke__">fge_ercynpr</span>([<span class="hljs-string">'0'</span>,<span class="hljs-string">'1'</span>], [<span class="hljs-string">' '</span>,<span class="hljs-string">'##'</span>], <span class="hljs-title function_ invoke__">fcevags</span>(<span class="hljs-title function_ invoke__">pue</span>(<span class="hljs-number">37</span>) . <span class="hljs-string">'025o'</span>, <span class="hljs-variable">$kf</span>[<span class="hljs-variable">$v</span>])), <span class="hljs-number">012</span>)) . <span class="hljs-string">"\a\a"</span>; + <span class="hljs-variable">$jf</span> = <span class="hljs-title function_ invoke__">neenl_znc</span>(<span class="hljs-title function_ invoke__">sa</span>(<span class="hljs-variable">$j</span>) => <span class="hljs-title function_ invoke__">vzcybqr</span>(<span class="hljs-string">', '</span>, <span class="hljs-variable">$j</span>), <span class="hljs-title function_ invoke__">neenl_puhax</span>(<span class="hljs-title function_ invoke__">neenl_znc</span>(<span class="hljs-title function_ invoke__">sa</span>(<span class="hljs-variable">$k</span>) => <span class="hljs-title function_ invoke__">fcevags</span>(<span class="hljs-string">'0k'</span> . <span class="hljs-title function_ invoke__">pue</span>(<span class="hljs-number">37</span>) . <span class="hljs-string">'07K'</span>, <span class="hljs-variable">$k</span>), <span class="hljs-variable">$kf</span>), <span class="hljs-number">10</span>)); + <span class="hljs-title function_ invoke__">cevags</span>(<span class="hljs-variable">$f</span>, <span class="hljs-variable">$g</span>, <span class="hljs-title function_ invoke__">fge_ebg13</span>(<span class="hljs-string">"<<<'Q'\a<span class="hljs-subst">{$f}</span>\aQ"</span>), <span class="hljs-title function_ invoke__">vzcybqr</span>(<span class="hljs-string">",\a"</span>, <span class="hljs-variable">$jf</span>)); Q; - $s = str_rot13($s); $xs = [ - 0x0AFABEA, 0x1F294A7, 0x1F2109F, 0x1F294A7, 0x0002800, 0x1F2109F, 0x0117041, 0x1F294A7, 0x1FAD6B5, 0x1F295B7, - 0x010FC21, 0x1FAD6B5, 0x1151151, 0x010FC21, 0x1F294A7, 0x1F295B7, 0x1FAD6B5, 0x1F294A7, 0x1F295B7, 0x1F8C63F, - 0x1F8C631, 0x1FAD6B5, 0x17AD6BD, 0x17AD6BD, 0x1F8C63F, 0x1F295B7, + <span class="hljs-variable">$s</span> = <span class="hljs-title function_ invoke__">str_rot13</span>(<span class="hljs-variable">$s</span>); <span class="hljs-variable">$xs</span> = [ + <span class="hljs-number">0x0AFABEA</span>, <span class="hljs-number">0x1F294A7</span>, <span class="hljs-number">0x1F2109F</span>, <span class="hljs-number">0x1F294A7</span>, <span class="hljs-number">0x0002800</span>, <span class="hljs-number">0x1F2109F</span>, <span class="hljs-number">0x0117041</span>, <span class="hljs-number">0x1F294A7</span>, <span class="hljs-number">0x1FAD6B5</span>, <span class="hljs-number">0x1F295B7</span>, + <span class="hljs-number">0x010FC21</span>, <span class="hljs-number">0x1FAD6B5</span>, <span class="hljs-number">0x1151151</span>, <span class="hljs-number">0x010FC21</span>, <span class="hljs-number">0x1F294A7</span>, <span class="hljs-number">0x1F295B7</span>, <span class="hljs-number">0x1FAD6B5</span>, <span class="hljs-number">0x1F294A7</span>, <span class="hljs-number">0x1F295B7</span>, <span class="hljs-number">0x1F8C63F</span>, + <span class="hljs-number">0x1F8C631</span>, <span class="hljs-number">0x1FAD6B5</span>, <span class="hljs-number">0x17AD6BD</span>, <span class="hljs-number">0x17AD6BD</span>, <span class="hljs-number">0x1F8C63F</span>, <span class="hljs-number">0x1F295B7</span>, ]; - $t = null.false; for ($i = 0; $i <= intdiv(__LINE__-035,6); ++$i) if (!isset($xs[$i])) break; else - $t .= implode("\n", str_split(str_replace(['0','1'], [' ','##'], sprintf(chr(37) . '025b', $xs[$i])), 012)) . "\n\n"; - $ws = array_map(fn($w) => implode(', ', $w), array_chunk(array_map(fn($x) => sprintf('0x' . chr(37) . '07X', $x), $xs), 10)); - printf($s, $t, str_rot13("<<<'D'\n{$s}\nD"), implode(",\n", $ws));</code></pre> + <span class="hljs-variable">$t</span> = <span class="hljs-literal">null</span>.<span class="hljs-literal">false</span>; <span class="hljs-keyword">for</span> (<span class="hljs-variable">$i</span> = <span class="hljs-number">0</span>; <span class="hljs-variable">$i</span> <= <span class="hljs-title function_ invoke__">intdiv</span>(<span class="hljs-keyword">__LINE__</span>-<span class="hljs-number">035</span>,<span class="hljs-number">6</span>); ++<span class="hljs-variable">$i</span>) <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$xs</span>[<span class="hljs-variable">$i</span>])) <span class="hljs-keyword">break</span>; <span class="hljs-keyword">else</span> + <span class="hljs-variable">$t</span> .= <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-title function_ invoke__">str_replace</span>([<span class="hljs-string">'0'</span>,<span class="hljs-string">'1'</span>], [<span class="hljs-string">' '</span>,<span class="hljs-string">'##'</span>], <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-title function_ invoke__">chr</span>(<span class="hljs-number">37</span>) . <span class="hljs-string">'025b'</span>, <span class="hljs-variable">$xs</span>[<span class="hljs-variable">$i</span>])), <span class="hljs-number">012</span>)) . <span class="hljs-string">"\n\n"</span>; + <span class="hljs-variable">$ws</span> = <span class="hljs-title function_ invoke__">array_map</span>(fn(<span class="hljs-variable">$w</span>) => <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">', '</span>, <span class="hljs-variable">$w</span>), <span class="hljs-title function_ invoke__">array_chunk</span>(<span class="hljs-title function_ invoke__">array_map</span>(fn(<span class="hljs-variable">$x</span>) => <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-string">'0x'</span> . <span class="hljs-title function_ invoke__">chr</span>(<span class="hljs-number">37</span>) . <span class="hljs-string">'07X'</span>, <span class="hljs-variable">$x</span>), <span class="hljs-variable">$xs</span>), <span class="hljs-number">10</span>)); + <span class="hljs-title function_ invoke__">printf</span>(<span class="hljs-variable">$s</span>, <span class="hljs-variable">$t</span>, <span class="hljs-title function_ invoke__">str_rot13</span>(<span class="hljs-string">"<<<'D'\n<span class="hljs-subst">{$s}</span>\nD"</span>), <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">",\n"</span>, <span class="hljs-variable">$ws</span>));</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 class="highlight">$ php toquine.php | php | php | php | ...</code></pre> <p> 実際にはもう少しパイプで繋げなければならない。 |
