一、魔數之定義
魔數這個詞在不同領域代表不同的含義。在計算機領域,魔數有兩個含義,一指用來判斷文件類型的魔數;二指程序代碼中的魔數,也稱魔法值。
- 大多數情況下,我們都是通過擴展名來識別一個文件的類型的,比如我們看到一個.txt類型的文件我們就知道他是一個純文本文件。但是,擴展名是可以修改的,當一個文件的擴展名被修改過,怎麼識別一個文件的類型呢?這就用到了我們提到的“魔數”。
- 所謂魔數和魔字符串就是指在代碼中出現但沒有解釋的數字常量或字符串,又稱魔法值。如果在某個程序中你使用了魔數,那麼在幾個月或幾年後你將很可能不知道它的含義是什麼。
很多類型的文件,其起始的幾個字節的內容是固定的(或是有意填充,或是本就如此)這幾個字節的內容也被稱爲魔數,因爲根據這幾個字節的內容就可以確定文件類型。有了這些魔術數字,我們就可以很方便的區別不同的文件。常見文件的魔數如下:
- JPEG (jpg),文件頭:FFD8FF
- PNG (png),文件頭:89504E47
- GIF (gif),文件頭:47494638
- TIFF (tif),文件頭:49492A00
- Windows Bitmap (bmp),文件頭:424D
- CAD (dwg),文件頭:41433130
- Adobe Photoshop (psd),文件頭:38425053
- Rich Text Format (rtf),文件頭:7B5C727466
- XML (xml),文件頭:3C3F786D6C
- HTML (html),文件頭:68746D6C3E
- Email [thorough only] (eml),文件頭:44656C69766572792D646174653A
- Outlook Express (dbx),文件頭:CFAD12FEC5FD746F
- Outlook (pst),文件頭:2142444E
- MS Word/Excel (xls.or.doc),文件頭:D0CF11E0
- MS Access (mdb),文件頭:5374616E64617264204A
- WordPerfect (wpd),文件頭:FF575043
- Postscript (eps.or.ps),文件頭:252150532D41646F6265
- Adobe Acrobat (pdf),文件頭:255044462D312E
- Quicken (qdf),文件頭:AC9EBD8F
- Windows Password (pwl),文件頭:E3828596
- ZIP Archive (zip),文件頭:504B0304
- RAR Archive (rar),文件頭:52617221
- Wave (wav),文件頭:57415645
- AVI (avi),文件頭:41564920
- Real Audio (ram),文件頭:2E7261FD
- Real Media (rm),文件頭:2E524D46
- MPEG (mpg),文件頭:000001BA
- MPEG (mpg),文件頭:000001B3
- Quicktime (mov),文件頭:6D6F6F76
- Windows Media (asf),文件頭:3026B2758E66CF11
- MIDI (mid),文件頭:4D546864
二、Class文件中的魔數
爲了方便虛擬機識別一個文件是否是class類型的文件,SUN公司規定每個class文件都必須以一個word(四個字節)作爲開始,這個數字就是魔數。魔數是由四個字節的無符號數組成的,Java的.class文件,開頭的4個字節是0xCAFEBABE。 這個魔數值在Java還被稱作“ Oak”語言的時候(大約是1991年前後)就已經確定下來了。它還有一段很有趣的歷史,據Java開發小組最初的關鍵成員Patrick Naughton 所說:“我們一直在尋找一些好玩的、容易記憶的東西,選擇0xCAFEBABE是因爲它象徵着著名咖啡品牌Peet's Coffee深受歡迎的Baristas咖啡。”下圖就是一個編譯後的class文件,可以看到文件開頭就是cafebabe。
三、魔數與Class文件的版本
緊接着魔數的4個字節存儲的是Class文件的版本號:第5和第6個字節是次版本號(Minor Version),第7和第8個字節是主版本號(Major Version)。
Java的版本號是從45開始的,JDK 1.1之後 的每個JDK大版本發佈主版本號向上加1(JDK 1.0~1.1使用了45.0~45.3的版本號),高版本的JDK能 向下兼容以前版本的Class文件,但不能運行以後版本的Class文件,因爲《Java虛擬機規範》在Class文 件校驗部分明確要求了即使文件格式並未發生任何變化,虛擬機也必須拒絕執行超過其版本號的Class 文件。
例如,JDK1.1能支持版本號爲45.0~45.65535的Class文件,無法執行版本號爲46.0以上的Class文件,而JDK1.2則能支持45.0~46.65535的Class文件。目前最新的JDK版本爲13,可生成的Class文件主版本號最大值爲57.0。
上圖中的版本號是34,對應的十進制爲52,所以對應的JDK版本爲1.8。
從JDK 1.1到13之間,主流JDK版本編譯器輸出的默認的和可支持的Class文件版本:
參考資料: