這篇博客是參照ASN.1 Java編譯器使用入門這篇介紹來的。安裝插件以及下載運行時環境都是必須的,前面一篇博客介紹了,直接在java語言中定義asn.1實體類,這裏,從asn文件開始,通過編譯生成java類,然後通過asnrt環境來進行asn.1編解碼的工作。
1、在eclipse中安裝asn.1插件,這樣,就可以創建asn.1的工程和模塊了。打開eclipse,依次選擇Help->Install New Software->填入 :http://www.asnlab.com/updates,回車,選擇sdk和plugin。如果只用java,在sdk中可以只選擇與java相關的sdk。
2、一路next,accept,finish等待安裝,如果失敗,重新安裝幾次。
3、注意一點,這個工具不是免費的,但是可以試用,試用期間,註冊一個license。最後,通過郵件的形式發送給你,將郵箱中的license粘貼到Windows->Preferences->ASN.1->Compiler->ASN.1 Java Compiler->Serial Number這裏。
4、安裝完成會提示重啓eclipse,重啓之後,新建->Other->ASN.1->ASN.1 Project。
5、新建->ASN.1 Module
6、編寫asn文件。
MyStudent.asn
MyStudent DEFINITIONS AUTOMATIC TAGS ::= BEGIN
EXPORTS Student;
IMPORTS ;
Student ::=SEQUENCE{
id INTEGER,
name VisibleString (FROM("a".."z"|"A".."Z"|"0".."9"|"./-_~%#")),
age INTEGER,
createDate GeneralizedTime
}
mystu Student ::= {
id 1,
name "buejee",
age 18,
createDate "20200519225445z"
}
END
通過安裝的插件,我們在編寫完成asn文件之後,在Outline視圖裏面可以清楚的看到MyStudent的一些屬性:
我們只有看到了Outline裏面有我們定義的SEQUENCE以及默認的值,我們的插件纔會生成正確的java類文件。生成的類文件會在output文件夾下的java文件夾內,如下所示:
這一步是自動生成java文件,也就是說我們在保存完asn文件之後,插件會自動生成,如果沒有生成,我們可以查看Outline視圖,是否正確顯示了我們定義的內容,也可以點擊Project->Build Automatically。
7、前面我們安裝的插件只是在eclipse中可以編譯asn生成java文件,還需要下載asnrt.jar就是運行時環境。
8、新建一個普通的工程,加入step7中下載的asnrt.jar到項目buildpath中,另外把我們在step6中生成的java文件加入到項目中,可以改變目錄,也可以默認,根據需要來設置,如果改變目錄,還需要手動改變他的package。這時候會提示缺少javax.validation的依賴,可以根據提示將其加入到buildpath中。項目結構如下所示:
9、接下來我們就可以進行asn.1編解碼的工作了,因爲我們在asn文件中定義的exports是Student,所以我們操作的主要類就是Student,而且它本身就已經包含了編解碼的方法:ber_encode,ber_decode
編寫StudentTest.java
package MyStudent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class StudentTest {
public static void main(String[] args) {
try {
Student stu = Student.mystu;
ByteArrayOutputStream out = new ByteArrayOutputStream();
stu.ber_encode(out);
byte[] data = out.toByteArray();
for(int i=0;i<data.length;i++) {
System.out.printf("%02X", data[i] & 0xFF);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
運行程序,打印結果爲:301F80010181066275656A6565820112830F32303230303531393232353434355A 。這個結果可以按照TLV的格式,拆成如下:
30 1F -- sequence
80 01 01 -- id
81 06 62 75 65 6A 65 65 -- name
82 01 12 -- age
83 0F 32 30 32 30 30 35 31 39 32 32 35 34 34 35 5A -- createDate
通過這個拆解的16進制,我們也能大概看出這個結果基本是符合我們定義的mystu的值的。
我們可以通過一個在線decode程序驗證這個編碼:
可以很清楚的看到,我們解碼的結果與我們在asn文件中定義的是一致的,id=1,name=buejee,age=18(0x12),
createDate=20200519225445Z。
10、最後解碼工作,其實就是根據step9中打印的16進制結果,進行decode即可,還是調用Student類的靜態方法ber_decode(),只不過這時候需要傳入一個ByteArrayInputStream對象。解析的結果,應該和我們通過在線工具解析的一致,這裏不再編碼演示。