そうだ、画像をバイナリ分解しよう

Blog Single

(ちょっとした遊びネタです。お付き合いくださいませ←)

最近テレビやとある記事を見ていて偶然何度も見かけた言葉。

「素因数分解」

懐かしいなと思いつつ、ふとコードで書いてみたくなりまして、
とりあえずPHPで書いてみる。

<?php
$question = "\033[0;36m素因数分解したい整数を指定してください。\033[0m\n";
echo $question;

// 対象の整数
$target = (int)trim(fgets(STDIN));
while (!$target) {
    echo "\033[0;31m数値が正しく指定されていません。\033[0m\n";
    echo $question;
    $target = (int)trim(fgets(STDIN));
}

$prime = 2;
$divisionTarget = $target;
$primeNumbers = [];
while ($prime !== $target) {
    if ($divisionTarget % $prime !== 0) {
        $prime++;
    } else {
        $divisionTarget = $divisionTarget / $prime;
        $primeNumbers[] = $prime;
    }
}
if (count($primeNumbers) === 0) {
    // 対象が素数の時
    $primeNumbers[] = $target;
}

$result = "\n{$target} を素因数分解すると、\n";
foreach($primeNumbers as $i => $number) {
    if ($i == count($primeNumbers) - 1) {
        $result .= "\033[0;32m{$number}\033[0m\nです!\n";
    } else {
        $result .= "\033[0;32m{$number} × \033[0m";
    }
}

echo $result;

うん。簡単すぎて何か面白くない←

単純に素因数分解をするのではなく、違うもので素因数分解を表したい。
そこで思いついたのは、

そうだ、画像をバイナリ分解しよう

…はい?

前提

ほとんどの方は知っていると思いますが、そもそも素因数分解とバイナリとは?という方は以下を読んでからお進みください。

バイナリ分解する

処理は単純にしたいので、設定としては以下のようにしました。

  • 使用言語: JavaScript
  • 画像ファイルを選択して、その画像のバイナリデータを分解するのみ

後ほどCodePenに公開しているものをお見せしますが、ここではバイナリ分解している処理のみ少し解説します。

まずはinput[type=file]で選択したファイルデータを、FileReaderでバイナリデータ化します。

// inputで選択したファイルデータ
var files = fileInput.files;
var reader = new FileReader();
reader.onload = (e) => {
    console.log(e.target.result); // <- これでバイナリ化した文字列が取得可能
}
reader.readAsBinaryString(files[0]);

取得したバイナリデータはそのままだと読むことはできないので、16進数に変換して読みやすくします。
ターミナルのxxdコマンドでも同じことはできますが….
あとは変換した文字列が何個あるかをカウントしていくだけです。

var uniqueBins = {};
for (var i = 0; i < str.length; i++) {
    var s = str.charCodeAt(i).toString(16);
    if (s.length == 1) {
        s = "0" + s;
    }
    uniqueBins[s] = uniqueBins[s] ? uniqueBins[s] + 1 : 1;
}

バイナリ分解の部分はこれだけです。
早速実際どういう動きをするのかお試しください!
(画像ファイルは一時的に処理をするだけですので、どこかに保存や送信されることはありません)

See the Pen Factoring by mao-miyaji (@mao-miyaji) on CodePen.

おわりに

今となってはなぜこんなことをしようと思ったのか、自分でも謎です←
技術的には特に難しいものも使わずに書いていますので、
見る方によっては、為になることもあればならないこともあるかと思いますが…
最後まで茶番にお付き合いいただき、ありがとうございます!

Posted by Mao Miyaji
千葉にある夢の国を愛して止まない、元「魚のお姉さん」のエンジニア。PHP, TypeScriptメインで、暇さえあれば色々な言語を一かじり。

Other Posts: