pycのマジックナンバーについて調べました。
Pythonのバイトコードのpycの最初の4バイトにはマジックナンバーがあって、どのバージョンで作成されたのか分かるようになっている。
各バージョンのマジックナンバーは
Lib/importlib/_bootstrap_external.pyを見れば分かる。
マジックナンバーは、各バージョンごとに用意されている2バイトの数値+168627479になっている。
pycからバージョンを調べる
まず、中身をみる。
$ od -tx1 a.pyc 0000000 17 0d 0d 0a b2 cb 3e 59 1f 00 00 00 e3 00 00 00 0000020 00 00 00 00 00 00 00 00 00 02 00 00 00 40 00 00 0000040 00 73 10 00 00 00 64 00 00 64 01 00 84 00 00 5a 0000060 00 00 64 02 00 53 29 03 63 02 00 00 00 00 00 00 0000100 00 02 00 00 00 02 00 00 00 43 00 00 00 73 08 00 0000120 00 00 7c 00 00 7c 01 00 17 53 29 01 4e a9 00 29 0000140 02 da 01 61 da 01 62 72 01 00 00 00 72 01 00 00 0000160 00 fa 04 61 2e 70 79 da 03 66 6f 6f 01 00 00 00 0000200 73 02 00 00 00 00 01 72 05 00 00 00 4e 29 01 72 0000220 05 00 00 00 72 01 00 00 00 72 01 00 00 00 72 01 0000240 00 00 00 72 04 00 00 00 da 08 3c 6d 6f 64 75 6c 0000260 65 3e 01 00 00 00 73 00 00 00 00 0000273
最初の4バイトは,17 0d 0d 0aなので、
>>> 23 + 13 * (1<<8) + 13 * (1<<16) + 10 * (1<<24) 168627479
マジックナンバーは168627479で、下2バイトをとりだす。
>>>168627479 & int("FFFF",16) 3351
あとは、一覧を眺めて同じやつを見つける。
# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations) # Python 3.5b2 3340 (fix dictionary display evaluation order #11205) # Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400) # Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286) # Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483 # Python 3.6a0 3361 (lineno delta of code.co_lnotab becomes signed) # Python 3.6a1 3370 (16 bit wordcode) # Python 3.6a1 3371 (add BUILD_CONST_KEY_MAP opcode #27140) # Python 3.6a1 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE # #27095) # Python 3.6b1 3373 (add BUILD_STRING opcode #27078) # Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes # #27985) # Python 3.6b1 3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL) # Python 3.6b1 3377 (set __class__ cell from type.__new__ #23722) # Python 3.6b2 3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257) # Python 3.6rc1 3379 (more thorough __class__ validation #23722) # Python 3.7a0 3390 (add LOAD_METHOD and CALL_METHOD opcodes)
バージョン3.5.2だね。
処理系からマジックナンバーを調べる
>>> import importlib.util >>> importlib.util.MAGIC_NUMBER b'\x17\r\r\n' >>> int.from_bytes(importlib.util.MAGIC_NUMBER,"little") 168627479