JVM虛擬機-Class文件之魔數

一、魔數之定義

魔數這個詞在不同領域代表不同的含義。在計算機領域,魔數有兩個含義,一指用來判斷文件類型的魔數;二指程序代碼中的魔數,也稱魔法值。

  • 大多數情況下,我們都是通過擴展名來識別一個文件的類型的,比如我們看到一個.txt類型的文件我們就知道他是一個純文本文件。但是,擴展名是可以修改的,當一個文件的擴展名被修改過,怎麼識別一個文件的類型呢?這就用到了我們提到的“魔數”。
  • 所謂魔數和魔字符串就是指在代碼中出現但沒有解釋的數字常量字符串,又稱魔法值。如果在某個程序中你使用了魔數,那麼在幾個月或幾年後你將很可能不知道它的含義是什麼。

很多類型的文件,其起始的幾個字節的內容是固定的(或是有意填充,或是本就如此)這幾個字節的內容也被稱爲魔數,因爲根據這幾個字節的內容就可以確定文件類型。有了這些魔術數字,我們就可以很方便的區別不同的文件。常見文件的魔數如下:

  1. JPEG (jpg),文件頭:FFD8FF 
  2. PNG (png),文件頭:89504E47 
  3. GIF (gif),文件頭:47494638 
  4. TIFF (tif),文件頭:49492A00 
  5. Windows Bitmap (bmp),文件頭:424D 
  6. CAD (dwg),文件頭:41433130 
  7. Adobe Photoshop (psd),文件頭:38425053 
  8. Rich Text Format (rtf),文件頭:7B5C727466 
  9. XML (xml),文件頭:3C3F786D6C 
  10. HTML (html),文件頭:68746D6C3E 
  11. Email [thorough only] (eml),文件頭:44656C69766572792D646174653A 
  12. Outlook Express (dbx),文件頭:CFAD12FEC5FD746F 
  13. Outlook (pst),文件頭:2142444E 
  14. MS Word/Excel (xls.or.doc),文件頭:D0CF11E0 
  15. MS Access (mdb),文件頭:5374616E64617264204A 
  16. WordPerfect (wpd),文件頭:FF575043 
  17. Postscript (eps.or.ps),文件頭:252150532D41646F6265 
  18. Adobe Acrobat (pdf),文件頭:255044462D312E 
  19. Quicken (qdf),文件頭:AC9EBD8F 
  20. Windows Password (pwl),文件頭:E3828596 
  21. ZIP Archive (zip),文件頭:504B0304 
  22. RAR Archive (rar),文件頭:52617221 
  23. Wave (wav),文件頭:57415645 
  24. AVI (avi),文件頭:41564920 
  25. Real Audio (ram),文件頭:2E7261FD 
  26. Real Media (rm),文件頭:2E524D46 
  27. MPEG (mpg),文件頭:000001BA 
  28. MPEG (mpg),文件頭:000001B3 
  29. Quicktime (mov),文件頭:6D6F6F76 
  30. Windows Media (asf),文件頭:3026B2758E66CF11 
  31. 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文件版本:

參考資料:

  1. https://blog.csdn.net/cold___play/article/details/105325698
  2. https://blog.csdn.net/shendeguang/article/details/18449627
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章