infomation
更新履歴
お勧め・人気記事
-
ファイルの中身を暗号化する by Python
ファイルの中身を暗号化する→文字列をビット演算するには? - 理想のユーザ・インターフェイスを求めて
先週に引き続き、日経ソフトウェア2009年12月号の特別付録『かんたん10分プログラミングレシピ』から、今日は”ファイルの中身の暗号化”のPython版を検討する。
http://itpro.nikkeibp.co.jp/article/COLUMN/20060131/228211/面白そうなのでやってみた。
#完全メモです。
◆ひとまずphpのソースを参考に書いてみる
coding.py
# coding:UTF-8 import sys inp = open(sys.argv[1],'rb') str_org = inp.read() allon = "a"*len(str_org) f = open('text.txt', 'w') f.write(allon^str_org) f.close()coding.txt
あ [22:38:34] : Yamb 2.0.0.8 started !!!#手近にあったyambのログ
実行
D:\>D:\coding.py D:\coding.txt Traceback (most recent call last): File "D:\\coding.py", line 8, in <module> f.write(allon^str_org) TypeError: unsupported operand type(s) for ^: 'str' and 'str'stringはサポートされてないと言われる。
◆ので ord() で一旦数値化した後、再度 chr() 1byte文字に変換する。
ord()やchr()でunicodeを扱うのはメンドクサイっぽいけど(下リンク参考)今回は排他的論理和取るだけでいいから関係ない。
404 Blog Not Found:perl, python & ruby - ord() vs. Unicode
404 Blog Not Found:perl, python & ruby - chr() vs. Unicodecoding2.py
# coding:UTF-8 import sys inp = open(sys.argv[1],'r') str_raw = inp.read() str_num = (ord(str) for str in str_raw) str_con = "".join([chr(str^255) for str in str_num]) f = open('text.txt', 'w') f.write(str_con) f.close()実行
D:\>D:\coding2.py D:\coding.txt D:\>type D:\text.txt }_ヘヘナフヌナフヒ「゚ナ゚ヲ梺旻ヘムマムマムヌ゚結檮禦已゙゙゙ D:\>D:\coding2.py D:\text.txt D:\>type D:\text.txt あ [22:38:34] : Yamb 2.0.0.8 started !!!今度は出来てますね。
◆画像ファイルとかも
やってみる。
実行
D:\>D:\coding.py D:\7365578.jpg D:\>dir text.txt 7365578.jpg Volume in drive D has no label. Volume Serial Number is 14F7-62F5 Directory of D:\ 2009/11/27 19:05 274 text.txt Directory of D:\ 2009/11/27 11:45 351,566 7365578.jpg 2 File(s) 351,840 bytes 0 Dir(s) 6,569,611,264 bytes free何故かファイルサイズが小さくなってる。
◆ひとまず
複合化して
D:\>D:\coding.py D:\text.txtバイナリエディタ(EmEditor)でdiffしてみる
diff実行
0Aの前に0Dが付いているみたい。0Aと0Dは改行文字なので何処かで変換されたのか。
それにファイルの切れ目の前後は 19と1Aで1Aはファイルの終わりのマークなのでこれが原因っぽい。とりあえず、検索に掛けてみる。
Windows版 Python で CGI 画像出力 (改行コードに注意) - rage2050の日記
それっぽいけど、これは標準出力の話らしい。バイナリファイルを開くときには、mode の値に 'b' を追加しなければなりません。
忘れてた。てことで、
◆修正
coding2p.py
# coding:UTF-8 import sys inp = open(sys.argv[1],'rb') str_raw = inp.read() str_num = (ord(str) for str in str_raw) str_con = "".join([chr(str^255) for str in str_num]) f = open('text.txt', 'wb') f.write(str_con) f.close()実行
D:\>D:\coding.py D:\7365578.jpg D:\>D:\coding.py D:\text.txt D:\>dir text.txt 7365578.jpg Volume in drive D has no label. Volume Serial Number is 14F7-62F5 Directory of D:\ 2009/11/27 19:33 351,566 text.txt Directory of D:\ 2009/11/27 11:45 351,566 7365578.jpg 2 File(s) 703,132 bytes 0 Dir(s) 6,563,459,072 bytes free再度diff
表示も問題なし。◆けどこのままだと
セキュリティ的に如何なのよ?と思うのでファイルをキーにしてみる。
codingPlus.py
# coding:UTF-8 import sys str_raw = open(sys.argv[1],'rb').read() str_len = len(str_raw) str_num = (ord(str) for str in str_raw) key_over = [False,] if "-k" in sys.argv: key_raw = open(sys.argv[sys.argv.index("-k")+1],"rb").read() key_len = len(key_raw) key_num = (ord(str) for str in key_raw) key_over = [True,str_len < key_len] str_con = [] if key_over[0]: if key_over[1]: for str in str_num: str_con.extend([chr(str^key_num.next())]) else: for num in key_num: str_con.extend([chr(str_num.next()^num)]) for str in str_num: str_con.extend([chr(str^255)]) else: for str in str_num: str_con.extend([chr(str^255)]) str_con = "".join(str_con) f = open('text.txt', 'wb') f.write(str_con) f.close()そのまま書くとアホみたいに汚くなる為にリスト内包記法ばらしたけど
もう少し綺麗な書き方はないものか◆関連する投稿
-
3件のコメント »
コメントをどうぞ

938 理想のユーザ・インターフェイスを求めて — 2009/11/28 土曜日 @ 1:10:30
[Python] なるほど…
検討していただいた。ありがたや。 ファイルの中身を暗号化する by Python -Tools&Toolz …
943 デフォルメ — 2009/12/20 日曜日 @ 22:51:41
面白いですね。
バイナリ時のfopenではmodeの記述にbも加える必要がある、というのは僕も結構忘れます。
あんまりバイナリをphpで操作しないんで。
956 銀月の符号 — 2010/2/4 木曜日 @ 23:35:01
[Python]ファイルとファイルの排他的論理和を取って簡易暗号化…
『 ファイルの中身を暗号化する by Python-Tools&Toolz』を読んで。自分でもやってみたくなったので、やってみた。 Python でファイルとある値、もしくはファイルとファイルの排他的論理和を求めて簡易暗号化する手順について自分なりに考えてみる。 a ^ b と書いて排他…