難読FizzBuzz書いた

JavaScriptで非常に読みにくいFuzzBuzzを書いてみた。

知らない人のために説明すると、FizzBuzzとは簡単な初心者向けのプログラミング教材みたいなので、
もともとは”せんだみつおゲーム”的なパーティゲームの一種なんだけれども、
それがプログラミングにも輸入された。
1から順番ずつ数えて、3の倍数だったらFizz、5の倍数だったらBuzz、3の倍数且つ5の倍数だったらFizzBuzzと表示して、それ以外だったらその時の数を表示するというプログラムを作るというもの

繰り返しと条件判定という2つのポイントがあるので、初学者の練習にもってこい。

なんだけれども、玄人も普通じゃないFizzBuzzを書こうということをよくやる。
一種の縛りプレイみたいなものだ。

僕の作った奴

早速だけけれども、コレが作ったFizzBuzz

((j)=>{let x=[];x.e=x.forEach;x.d=x.push;let tt=[j,j,j];let vv=[j,j,j,j,j];let [dd,ee,ff,gg,hh]=['f','i','z','u','b'];let [ii,jj]=[j(j(j(dd,ee),ff),ff),j(j(j(hh,gg),ff),ff)];tt.l=tt.length;vv.f=vv.length;((a)=>{let [f,b,t,g,z,l,y,e,d]=[ii,jj,tt.l,vv.f,(0xDF/0xDF-0xAE/0xAE),console.log,(aa,aaa)=>aa%aaa,(bb,bbb)=>bb===bbb,(cc,ccc)=>cc&amp;&amp;ccc];    let h=(n)=>{for(i=z;i<n;i++)x.d(i);return x};h(a).e((c)=>{(d(e(y(c,t),z),e(y(c,g),z)))?l(j(f,b)):(e(y(c,t),z))?l(f):(e(y(c,g),z))?l(b):l(c)})})(0xEA)})((ss,sss)=>ss.concat(sss));

ワンライナー、この一行だけをnode.jsで実行するとある程度大きい数値までFizzBuzzを繰り返してくれる

きっとブログだと見づらいから、画像も付けておく

難読化のポイント

難読化といっても、トランスパイラで最適化させたようなもんじゃない。
難読化のために非常に回りくどく書いている。

アロー演算子を使った無名関数で何重にもくるむ。
これでどこからどこまでかスコープか全然わかんない。

console.log forEach push concatなどの元々ある関数は、変なところで一文字の変数に代入している。
だから呼ばれているところがどこかわかんない。

基本的に変数は一文字か、アルファベットの繰り返しにしている

FizzBuzzという文字を分解してワザワザ結合している。
これでぱっと見ても何のコードかわからないだろう

ifは()?:の構文に置き換える。
JavaScriptにはifを1行で表せる別の構文があったのだ。

変数の宣言は let [] = []の構文を使う。
まとめて宣言と初期化ができるのだ。

なるべく、スペースと;をなくして、できればreturnも消せるところは消している。

数値リテラルはなるべく使わないようにした。
適当な配列を作って、length値で置き換えているのと、
16進数同士の計算で表現している。

evalやBASE64で変化させるのは邪道というつもりでやった。
evalは文字列をコードとして解釈して動かせるというのと、BASE64化させてデコードしてevalして動かすというのはよくマルウェアが使う手法だけれども
それは流石に際限なく難読化できるのでやめた


スポンサードリンク

関連コンテンツ