これは備忘録です.発想は単純だけど意外と面倒だった.
もちべ
長いコードを画像化して投げればいいのでは?
てじゅん
1. コードをbase64にする
まずはソースコードを文字にして画素値にさせる.
中間的な形式としてPPM画像で出力させる.
PPMで画像化するので3文字ごとに変換する.AAABBCCCC
ならば0 0 0\n 1 1 2\n 2 2 2
とさせる
encode.py
import sys
import base64
argv = sys.argv
f = open(argv[1], 'r').read()
enc = base64.b64encode(bytes(f,"utf-8"))
tri = []
for i in range(0,len(enc),3):
e = enc[i:i+3]
while len(e) != 3:
e += b"="
tri.append(e)
b2i = {c: i for i,c in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=')}
im = []
for t in tri:
r = []
for c in t.decode('utf-8'):
r.append(b2i[c])
im.append(r)
ims = "\n".join([f"{c[0]} {c[1]} {c[2]}" for c in im])
print(ims)
python encode.py src.py > image.ppm
2 PPMをPNGにする
画像にするためには行数を縦横分割する必要がある.素因数分解して縦横比がちょうどよくなるような約数をえらぶ.
例えば行数が12486行の場合約数は$2,3,2081$だが2行増やした12488は$2,2,2,7,223$と正方形に近くなるように約数が選べるため上の出力結果に64 64 64
という行を追加してパディング.(64は=
に相当するので)
47 26 22
53 33 25
54 21 51
11 54 33
47 25 54
20 46 28
6 57 39
...
8 34 36
64 64 64 <-ここに追加
64 64 64 <-ここに追加
つぎに頭にメタ情報を付加する
P3
横の画素数 縦の画素数
画素の最大値
...
image.ppm
P3
223 56
255
47 26 22
53 33 25
54 21 51
11 54 33
47 25 54
20 46 28
6 57 39
...
8 34 36
64 64 64
64 64 64
あとはconvertでpng化
convert image.ppm image.png
3 Twitterに投げる
あとはこれをメディアに付加して#シェル芸
タグをつけて投稿
python -c '
import numpy as n
import matplotlib.pyplot as p
f={i:c for i,c in enumerate("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")}
print("".join([f[int(255*i)] for i in p.imread("/media/0","png").flatten()]),end="")
'|base64 -d|python
#シェル芸
文字制限ギリギリです.画像は/media/0
に格納される仕様なのでそれを利用する.
実行例
https://t.co/xyBv6ejSGj pic.twitter.com/1FSVyLeNVF
— シェル芸bot (@minyoruminyon) January 10, 2020
実際これは3万字近いヤツなので画像万歳といったところである.
なお,もととなる関数はWolflam Alphaより拝借している.