將python源程式編譯為pyc或pyo位元組碼程式
現在面臨另外一個問題,因為最終密文形式的密碼還是需要解密後才能使用的,上邊提到的用於解密配置檔案中的密文的中間層正是用於此目的。若惡意使用者獲取到了相關檔案,很容易根據檔案中的程式碼推測出加密使用的演算法,也很容易獲取的明文的密碼,因此現在需要一種方式將python原始碼轉換成不能被“小人”輕易讀取的檔案形式。
怎麼轉換呢?其實通過將python源程式.py檔案編譯為位元組碼檔案.pyc或.pyo就可以很好的達到上述目的(儘管這仍有可能被惡意著反編譯為.py原始檔,但至少算是有加強了一層防護,是無意的“君子”不至於這麼輕鬆獲取密碼。)
那麼該如何編譯python源程式呢?
可以有多重形式:
python -m py_compile file.py #把單個.py檔案編譯為位元組碼檔案
python -m py_compile /path/to/src/ #批量生成位元組碼檔案,/path/to/src/是包含.py檔名的路徑
python -m compileall file.py #把單個.py檔案編譯為位元組碼檔案
python -m compileall /path/to/src/ #批量生成位元組碼檔案,/path/to/src/是包含.py檔名的路徑
或者:
python -O -m py_compile file.py
python -O -m py_compile /path/to/src/
python -O -m compileall file.py
python -O -m compileall /path/to/src/
或者
python -OO -m py_compile file.py
python -OO -m py_compile /path/to/src/
python -OO -m compileall file.py
python -OO -m compileall /path/to/src/
或者通過指令碼來編譯:
import py_compile
py_compile.compile('file.py')
import compileall
compileall.compile_file('file.py')
import compileall
compileall.compile_dir('/path/to/src/')
compileall.compile_path()
具體引數:
compile(file, cfile=None, dfile=None, doraise=False)
Byte-compile one Python source file to Python bytecode.
Arguments:
file: source filename
cfile: target filename; defaults to source with 'c' or 'o' appended
('c' normally, 'o' in optimizing mode, giving .pyc or .pyo)
dfile: purported filename; defaults to source (this is the filename
that will show up in error messages)
doraise: flag indicating whether or not an exception should be
raised when a compile error is found. If an exception
occurs and this flag is set to False, a string
indicating the nature of the exception will be printed,
and the function will return to the caller. If an
exception occurs and this flag is set to True, a
PyCompileError exception will be raised.
compile_dir(dir, maxlevels=10, ddir=None, force=0, rx=None, quiet=0)
Byte-compile all modules in the given directory tree.
Arguments (only dir is required):
dir: the directory to byte-compile
maxlevels: maximum recursion level (default 10)
ddir: the directory that will be prepended to the path to the
file as it is compiled into each byte-code file.
force: if 1, force compilation, even if timestamps are up-to-date
quiet: if 1, be quiet during compilation
compile_file(fullname, ddir=None, force=0, rx=None, quiet=0)
Byte-compile one file.
Arguments (only fullname is required):
fullname: the file to byte-compile
ddir: if given, the directory name compiled in to the
byte-code file.
force: if 1, force compilation, even if timestamps are up-to-date
quiet: if 1, be quiet during compilation
compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0)
Byte-compile all module on sys.path.
Arguments (all optional):
skip_curdir: if true, skip current directory (default true)
maxlevels: max recursion level (default 0)
force: as for compile_dir() (default 0)
quiet: as for compile_dir() (default 0)
註解:
-m引數相當於指令碼中的import,這裡的-m py_compile 相當於上面的 import py_compile,也即把後邊跟隨的庫模組當做指令碼執行。這樣生成的位元組碼檔案字尾名為.pyc
-O引數表明要生成更加緊湊的優化後的位元組碼,-OO會進一步移除-O選項生成的優化後的位元組碼檔案中的文件字串。這樣生成的位元組碼檔案字尾名為.pyo,對於.pyo檔案可以通過 python命令加-O引數執行匯入了該模組的python程式來呼叫。
需注意的是,不同版本編譯後的pyc檔案是不同的,比如2.5編譯的pyc檔案2.4版本的python是無法執行的。