From 98682c7a8792e7e79e487fea5024d25cee5aa310 Mon Sep 17 00:00:00 2001
From: nsfisis contained unnecessary whitespaces inside it
---
.../2022-04-09/phperkaigi-2022-tokens/index.html | 76 +++++++---------------
1 file changed, 23 insertions(+), 53 deletions(-)
(limited to 'public/posts/2022-04-09/phperkaigi-2022-tokens')
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 以上が必要なので注意。
- <?php
+ <?php
declare(strict_types=0O1);
@@ -135,8 +134,7 @@
$👉, $👍, $👍, $📝,
$👉, $👎, $📝,
$👈, $📝,
- ]);
-
+ ]);
この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。 @@ -165,8 +163,7 @@ なお、brainf*ck プログラムを普通の書き方で書くと、次のようになる。
-
- + + + + + + + + + +
+ + + + + + + + + + +
[
> + + +
> + + + + +
@@ -187,8 +184,7 @@
< .
> + + .
> - .
-< .
-
+< .
実行結果はこちら:https://ideone.com/22VWmb @@ -271,9 +267,7 @@ ソースコードのライセンスを示したこの部分だが、
-
- https://creativecommons.org/publicdomain/zero/1.0/
-
+ https://creativecommons.org/publicdomain/zero/1.0/
完全に合法な PHP のコードである。https:部分はラベル、//以降は行コメントになっている。
@@ -286,13 +280,11 @@
ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。 PHP では、型変換を利用することで任意の整数を作り出すことができる。
- assert(0 === +!![]);
+ assert(0 === +!![]);
assert(1 === +![]);
assert(2 === ![]+![]);
assert(3 === ![]+![]+![]);
-assert(10 === +(![].+!![]));
-
+assert(10 === +(![].+!![]));
[]に!を適用するとtrueが返ってくる。それに+を適用すると、boolからintヘの型変換が走り、1が生成される。10はさらにトリッキーだ。まず1と0を作り、.で文字列として結合する ('10')。これに+を適用すると、stringからintへの型変換が走り、10が生まれる (コード量に頓着しないなら、1を 10 個足し合わせてももちろん 10 が作れる)。
@@ -333,8 +325,7 @@ assert(10 === +(![].+!![]));
ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。
- <?php
+ <?php
/*********************************************************
* This program displays a PHPer token. *
@@ -367,8 +358,7 @@ assert(10 === +(![].+!![]));
$x = str_replace(search: ['0', '1'], replace: [' ', '#'], subject: $x);
$x = implode("\n", str_split($x, length: 5));
echo "{$x}\n\n";
- }
-
+ }
さて、この問題はさきほどのように単純に実行しただけでは、謎のブロックが表示されるだけでトークンは得られない。 トークンを得るためには、ソースコードを読み、定数Nを特定する必要がある。
@@ -384,43 +374,33 @@ assert(10 === +(![].+!![]));
まずはソースコードを読んでいく。
- $token = [
+ $token = [
// 略
- ];
-
+ ];
数値からなる$tokenがあり、各要素をループしている。
- $x = $x ^ N;
-
+ $x = $x ^ N;
まずは排他的論理和 (xor) を取り、
-
- $x = sprintf('%025b', $x);
-
+ $x = sprintf('%025b', $x);
二進数に変換して、
-
- $x = str_replace(search: ['0', '1'], replace: [' ', '#'], subject: $x);
-
+ $x = str_replace(search: ['0', '1'], replace: [' ', '#'], subject: $x);
0 を空白に、1 を#にし、
- $x = implode("\n", str_split($x, length: 5));
-
+ $x = implode("\n", str_split($x, length: 5));
5文字ごとに区切ったあと、改行で結合している。
@@ -474,16 +454,13 @@ assert(10 === +(![].+!![]));
Nは高々
- assert(0 <= N && N <= 0b11111_11111_11111_11111_11111);
-
+ assert(0 <= N && N <= 0b11111_11111_11111_11111_11111);
なのでブルートフォースしてもよいが、ここではブルートフォースしない方法を紹介する。
-
- <?php
+ <?php
$x = 0x14B499C;
@@ -498,15 +475,13 @@ assert(10 === +(![].+!![]));
"#####\n" .
" # # \n" .
"#####\n" .
- " # # ");
-
+ " # # ");
この一連の変換に対する逆変換を考えると、次のようになる。
-
- <?php
+ <?php
$x =
" # # \n" .
@@ -521,8 +496,7 @@ $x = bindec($x);
$n = $x ^ 0x14B499C;
-echo "N = $n\n";
-
+echo "N = $n\n";
これを実行すると、Nが得られる。
@@ -536,8 +510,7 @@ echo "N = $n\n";
ソースコードはこちら。
- <?php
+ <?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 "N = $n\n";
$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));
-
+ printf($s, $t, str_rot13("<<<'D'\n{$s}\nD"), implode(",\n", $ws));
コメントにもあるとおり、次のようにして実行すれば答えがでてくる。
-
- $ php toquine.php | php | php | php | ...
-
+ $ php toquine.php | php | php | php | ...
実際にはもう少しパイプで繋げなければならない。 -- cgit v1.2.3-70-g09d2