190 likes | 369 Views
「デモ自慢」 ppencode. Shibuya Perl Mongers 竹迫 良範. アンケート. 好きな人 の割合. 言語. “ ~が好き ”. “ ~が嫌い ”. Perl. 212. 34. 81%. Ruby. 61. 15. 80%. PHP. 15. 4. 79%. Python. 29. 2. 93%. ※ 参考: Google の検索結果. Perl が好きな人/嫌いな人(挙手!). Perl がもっと好きになるかも?. Perl が嫌いな理由ベスト3(勝手に) 変数にいちいち $ を付けるのが面倒
E N D
「デモ自慢」 ppencode Lightweight Language Day and Night Shibuya Perl Mongers 竹迫 良範
アンケート 好きな人 の割合 言語 “~が好き” “~が嫌い” Perl 212 34 81% Ruby 61 15 80% PHP 15 4 79% Python 29 2 93% ※参考:Googleの検索結果 • Perlが好きな人/嫌いな人(挙手!) Lightweight Language Day and Night
Perlがもっと好きになるかも? • Perlが嫌いな理由ベスト3(勝手に) • 変数にいちいち $ を付けるのが面倒 • 文末のセミコロン ; を付け忘れてしまうことが… • とにかく、見た目からしてイヤだ! • Perlが好きになる解決方法 • 変数なんて使わなければイイじゃん! • セミコロンを使わないで書けばイイじゃん! • 見た目のインパクト重要! → Let’s 予約語プログラミング♪ Lightweight Language Day and Night
Quiz: これは何をするプログラムでしょう? #!/usr/bin/perl sin cos and s qq qx xor s x x print uc chr lc ord qq sleep times x xor int log cos xor eval and eval and print uc chr ord scalar reverse qq exit binmode xor qq write qw xor print uc chr ord scalar reverse qw tell my print 正解 → 標準出力に “LLDN” という文字列を出力するプログラム Lightweight Language Day and Night
Just Another Perl Hacker • はじまりは JAPH • 「just another perl hacker」を表示する80x40以内のPerlプログラム • もともとはUSENETの署名につけて、自分のPerl好きをアピールするものだった ● 記録されている最初のJAPH @a=split(/(\d)/, "4Hacker,2another3Perl1Just"); shift(@a);%a=@a; print "@a{1..4}"; Randal Schwartz 1 Feb 1990 22:28:58 GMT Shibuya Perl Mongersテクニカルトーク#5 (2004年12月16日) http://shibuya.pm.org/blosxom/techtalks/200412.html 税別¥1,500- 水野 貴明 (著) Lightweight Language Day and Night
(例)STAR WARS #!/usr/local/bin/perl undef$/;$_=<DATA>;y/ODA\n / /ds;@yoda=map{length}split;print chr oct join('',splice(@yoda,0,3))-111 while@yoda; __DATA__ 00O00O000O00O0000 000O DD000000O0 0DO0000000O0000O00 O00000 00O00000O0O 0000 0O0 O00 O00 00D 0DO 00O0 0O0 00D 000 DO0D00000D 0O00 DOD 000000O00000 000 O00O DD0000D000O0 000 0O00O0000D00DO 0OD D00O000D00O0 00000DO00O0 000 000O 00D0 O0D O00000O0DO0 0O000 OD0D O00O0 0000 DDDO000000 O00O000000 0O000 O00DDO 00000 0O0D00 00O0O00000O 0O00O000000 0O0O00OD00000DDD 00O 0D0 DDD D0O 00O0D 00000O00000000 O00 DO0 D00D00O000 00D00 D0O00 O0000 000O000O00DO 000 00O0 0OD00 O00 000 0O000D000O00O0 000 0D0O000000O00O00 0 0 0O0D 0000 0O0 0O0000000O000O http://www.cpan.org/misc/japh Lightweight Language Day and Night
Obfuscated Programming Perlプログラマのレベル10 Perl カンファレンスに出席するなど、Perl コミュニティへの関与を深める。… レベル 9 Perl の obfuscation コンテストや「golf」コンテストに参加する。… レベル 10 http://d.hatena.ne.jp/naoya/20050809/1123563794 • 難読プログラミング • JAPH をさらに発展。見た目重視。表示するのが「just another perl hacker」でなくてもいい。 • 普段あまり使われないテクニックに注目する。 • 80x40にとらわれず、長くても面白ければいい。 Lightweight Language Day and Night
(例)こんにちは世界 package Earth;sub Greet{ %_=('Y','~');$_='$;=!(Middle Earth.age~~~<Eart~~~~~~~~~~~~~h .age)?!(defined$ti~~~~~~~~~~~mez~~~On e[2])?!(push@time~~~~~~~~~~~~~~~~Zone,loc ~altime())?rotation?~~~~~~~~~~~~~q~~?The Worl ~~d?:q:[\w]::q=[\~~~~~~~~~~~~~~~~~d~a-f]=:q?..~~ ~~~?:q:.:;"42b3d3~~~~~~~~~~~~~~~~~~~~~728656c6c6f6 ~~~~~0277f627c64672~~~~~~~~~~~~~~~~~~~~~b3072796e647 ~~~~~~~42b3b3rg7d"=Ym~~~~~~~~~~~~~~~~~~~\$;~~*\;p~~~~u ~~~~~~~~~sh@_,$&;bless~~~~~~~~~~~~~~~~~~~~~~~~~$c~~~~~~~ ~~~~~~~~~o~ntine~~~~~nt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~s=\~~~~~~~$~~~~~~~~~~~~~~~~~~~~~~~pangaea~~~~ ~~~~~~~~~~~~~~~;{l~~~~~~~~~~~~~~~~~~~~~~~~~~~~ocal@_;local$; ~~~~~~~~~~~~~~~~~="o~~~~~~~~~~~~~~~~~~~~~~~~~cean";$^A=(defi ~~~~~~~~~~~~~~~~~~~n~~~~~~~~~~~~~~~~~~~~~~~~~ed$continents)? ~~~~~~~~~~~~~~~~~~~(vec(~~~~~~~~~~~~~~~~~~~~~~$;, YYsplit(\' ~~~~~~~~~~~~~~~~~\',${\$;}~~~~~~~~~~~~~~~~~~~~~~)%3,YYsplit( ~~~~~~~~~~~~~~~~q??,$;)**2-~~~~~~~~~~~~~~~~~~~~~~(($;=Ytr/oa ~~~~~~~~~~~~~~~~eiu//)**2))=~~~~~~~~~~~~~~~~~~~~~~=28160)?q: ~~~~~~~~~~~~~~~~~.::q?!?:\'?~~~~~~~~~~~~~~~~~~~~~~\';}$^A=Ys ~~~~~~~~~~~~~~~~:\Q.\E:pack(~~~~~~~~~~~~~~~~~~~~~~\'h*\',j ~~~~~~~~~~~~~~~~~oin(q(),~~~~~~~~~~~~~~~~~~~~~~~grep{$_= ~~~~~~~~~~~~~~~~~~Ym,$,,}~~~~~~~~~~~~~~~~~~~~~~~split(" ~~~~~~~~~~~~~~~~~",@_~~~~~~~~~~~~~~~~~~~~~~~~~~[0])) ~~~~~~~~~~~~~~~~):e~~~~~~~~~~~~~~~~~~~~~~~~~~~gexe ~~~~~~~~~~~~~~~;$d~~~~~~~~~~~~~~~~~~~~~~~~~~~="s ~~~~~~~~~~~~~~ort~~~~~~~~~~~~~~~~~~~~~~~~~~<= ~~~~~~~~~~~~>,~~~~~~~~~~~~~~~~~~~~~~~~~~YY ~~~~~~~~~~~@_~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~"~~~~~~~~~~~~~~~~~~~';; s,(~|\r|\n|\s),,g;s.Y.\x7e.g; eval};Greet;'the world'; http://www.perlmonks.org/index.pl?node_id=329174 Lightweight Language Day and Night
ppencode のご紹介 Lightweight Language Day and Night Fun With Reserved Keywords を 自動生成するプログラム
ppencode の使い方 • ppencode とは? • 入力文字列を出力する(予約語のみで構成された) Perlプログラムを自動出力するPerlプログラム • コマンド使用法 $ echo -n "Have fun!" | ppencode #!/usr/bin/perl cos xor print chr ord uc qq chr uc xor print chr ord qq each ge xor print chr ord qq eval ge xor print chr ord qw x eq x xor print chr ord qq q eq xor print chr ord qw q fcntl q xor print chr ord qw q uc q xor print chr ord qw q no q xor print chr length q q while syswrite setgrent symlink q Lightweight Language Day and Night
Perlの予約語 (220) ■ 演算子/制御子 (38) lt gt le ge eq ne cmp not and or xor if else elsif while for foreach continue goto last local map my next redo require return use tr y s m q qq qr qw qx x ■ 標準関数 (182) 数字があるため除外 abs accept alarm atan2 bind binmode bless caller chdir chmod chomp chop chown chr chroot close closedir connect cos crypt dbmclose dbmopen defined delete die do dump each eof eval exec exists exit exp fcntl fileno flock fork formline getc getlogin getpeername getpgrp getppid getpriority getpwnam getgrnam gethostbyname getnetbyname getprotobyname getpwuid getgrgid getservbyname gethostbyaddr getnetbyaddr getprotobynumber getservbyport getpwent getgrent gethostent getnetent getprotoent getservent setpwent setgrent sethostent setnetent setprotoent setservent endpwent endgrent endhostent endnetent endprotoent endservent getsockname getsockopt glob gmtime grep hex import index int ioctl join keys kill lc lcfirst length link listen localtime log lstat mkdir msgctl msgget msgrcv msgsnd no oct open opendir ord pack pipe pop pos print printf push quotemeta rand read readdir readlink recv ref rename reset reverse rewinddir rindex rmdir scalar seek seekdir select semctl semget semop send setpgrp setpriority setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat study substr symlink syscall sysread system syswrite tell telldir tie time times truncate uc ucfirst umask undef unlink unpack untie unshift utime values vec wait waitpid wantarray warn write Lightweight Language Day and Night
使用禁止文字 • 数字 • 0 1 2 3 4 5 6 7 8 9 を使っちゃ駄目! • 記号 • 変数 $, @, %, セミコロン ; カンマ , も駄目! • クォート ’ダブルクォート ”も使用禁止! • その他 \ () {} [] + - : ! ? & | #.. も! • もちろん・・・ • ゴースト演算子 =()= • シャクトリムシ演算子 ~~ • スペースステーション演算子 -+- もってのほか! Lightweight Language Day and Night
ppencode の作り方 • ppencode とは? • 入力文字列を出力する(予約語のみで構成された) Perlプログラムを自動出力するPerlプログラム • いわゆるコードジェネレータ • その前段階として gen_ppencode • ppencode を生成するためのPerlプログラム • コードジェネレータのコードジェネレータ • 予約語の組み合わせは膨大 (220 x 220 x …) • 後途のヒューリスティックを実装 • 出力にゆらぎを持たせる工夫(改善の余地あり) Lightweight Language Day and Night
予約語プログラミングのテクニック解説 • セミコロン ; の代わりに xorを使う • q/??/ → q x??x → q else → ’ls’ • qq/??/ → qqx??x → qq else → ”ls” • qw(?? ??) → qw x?? ??x → qw sin cos • print chr ord ”abc”→ 先頭文字 a を出力 • reverse → 文字列を反転 → 末尾文字を出力 • uc, uppercase → tr/a-z/A-Z/ • length → 文字列の長さ → 任意のASCIIコード Lightweight Language Day and Night
Ajaxっぽいデモ http://namazu.org/~takesako/ppencode/demo.html Lightweight Language Day and Night
ppencode って役に立つの??? • 一つのエンコード方式として・・・ • Perl の実行環境そのものがデコーダ • そこに Perl さえあれば解凍可能! • 解凍プログラムのインストールが不要! • cd /usr/bin; sudo ln –s perl ppdecode • uuencode の代わりに! • 愛の告白に・・・ • “I love you”を表示するプログラムをメールで送付 • 内気なGeekでも照れずに告白! Lightweight Language Day and Night
参考リンク • 洗練されたPerl: JAPHのすばらしさ • http://www-6.ibm.com/jp/developerworks/linux/011026/j_l-japh.html • Perl Monks - Fun With Reserved Keywords • http://www.perlmonks.org/index.pl?node_id=290607 • [CPAN] Acme::EyeDrops • http://search.cpan.org/~asavige/Acme-EyeDrops-1.50/ Lightweight Language Day and Night
まとめ • Let’s 予約語プログラミング♪ • Perl 以外の言語でも実装できますか? • awk ? • Haskell ? • Lisp ? • ML ? • Perl → OK ! • PHP ? • Python ? • Ruby ? 挑戦者求む! Lightweight Language Day and Night
ご清聴ありがとうございました Lightweight Language Day and Night http://namazu.org/~takesako/