私のアカウント名は @phigasui です。
成果物は下記の通りです。
import this;''.join(this.d[c]for c in'cuvtnfhv')
''.join([c.__doc__[ord(c)] for c in '\x95j13L\x00$1'])
this
Module に頼る
まずは何らかの文字列があればそこから p
, h
, i
, g
, a
, s
, u
を取り出せれば良いなと思いました。
文字列を得る
Python の built-in で文字列って何があったかなーと思って思い出したのが。
import this
Zen of Python が表示されるアレですね。
この this
Module には c
, d
, i
, s
の謎の4つの属性があります。
>>> dir(this)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'c', 'd', 'i', 's']
this.d
には dict
型のデータ、this.s
には謎の文字列、 this.c
this.i
には謎の数字が入っています。
何が行われているかは this.__file__
を開けばわかるのですが
this.d
には特定のアルファベットとそのアルファベットの Unicode コードポイントを13ずらしたアルファベットの組みが入っているようです。
`this.py`の内容
s = """Gur Mra bs Clguba, ol Gvz Crgref
Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""
d = {}
for c in (65, 97):
for i in range(26):
d[chr(i+c)] = chr((i+13) % 26 + c)
print("".join([d.get(c, c) for c in s]))
c
, i
はその dict
を作った時の残骸ですね。
で、this.s
を this.d
に従って変換すると Zen of Python が完成するようになっています。
私がやりたかったことをやっている...
ということで、this.d
を使えば簡単に任意の文字列抽出できそうなことがわかりました。
任意の文字を抽出する
'phigasui' の文字のキーを取り出したいので、this.d
をひっくり返してとってきます。
d = {v: k for k, v in this.d.items()}
print(''.join([d[c] for c in 'phigasui']))
'cuvtnfhv'
無事、this.d
から phigasui
を得るための文字列を得ました。
完成
import this;''.join(this.d[c]for c in'cuvtnfhv')
this.s
を使うでもいいなと思いつつせっかくなので他の文字列を探します。
docstring に頼る
コード中に存在している文字列といえば docstring(ドキュメンテーション文字列)ですね。
Python では各オブジェクトに __doc__
の属性を持っています。
これを使って phigasui
の各文字の index をとってくれば良さそうです。
index の数字のリストだと冗長なので文字列にします。
print(''.join([chr(''.__doc__.find(c)) for c in 'phigasui']))
'\x95j13L\x00$1'
無事、str
docstring から phigasui
を得るための文字列を得ました。
完成
''.join([c.__doc__[ord(c)] for c in '\x95j13L\x00$1'])
もっとおもしろいのあったらぜひ教えてください
本当は Julia ではじめたので Julia 編もそのうち。