2016-05-05 35 views
4

我是新來的ASN.1編碼流,我很難找到一個免費的類編譯器和解碼器,最好是Java。與自動標籤一起工作的開源Java ASN.1解碼器

我有一個編碼的十六進制字符串:

String test("30820274800200a2810105820410300c3d830401bb0afc84... 

這裏是符號的一個例子:

SEMI DEFINITIONS AUTOMATIC TAGS ::= BEGIN 

IntersectionSituationData ::= SEQUENCE { 
    dialogID  SemiDialogID,     -- 0xA2  
    seqID   SemiSequenceID,     -- 0x05 Data 
    groupID   GroupID,       
    -- Some more members 
} 

SemiDialogID ::= ENUMERATED { 
    intersectionSitDataDep  (162), -- 0xA2 
    -- additional DialogIDs 
} 
SemiSequenceID ::= ENUMERATED { 
    data    (5), -- Data 
    -- additional SeqIDs 
} 

我開始使用JAC:https://sourceforge.net/projects/jac-asn1/ 但它不支持自動標記。

我接下來試過jASN1:https://www.openmuc.org/asn1/ 它沒有說它是否支持自動標籤。它似乎沒有抱怨地編譯Notation,但我無法正確解碼,它看起來像標籤如果錯了。

如果我們把編碼字符串的開頭:30 82 02 74 80 02 00 A2 ... 這是我的理解:

30 = Sequence 
82 = Length encoded in 2 octets 
02 74 = Length = 2x256 + 7x16 +4 == 638 bytes, correct 
80 ?? is this a result of automatic encoding? x80= 128= 8th bit set = context-specific class, number 0? 
02 = length of value is 2 octets 
00 a2 is value == xA2 as expected from SemiDialogID 

但如果我編碼 「IntersectionSituationData」 的測試中,我得到如下:30 81 8a 0a 02 00 a2 即類型爲'x0a'== 10,它是ASN.1 Universal ENUMERATED。這是有道理的形式看他通知,但我猜測自動標記正在被jASN1忽略。當我看到生成的Java類,我們看到SemiDialogID延伸BerEnum,它採用通用CLAS標識符:

// SemiDialogID.java 
public class SemiDialogID extends BerEnum { 
    ... 
} 

//BerEnum.java 
public class BerEnum extends BerInteger { 

    public final static BerIdentifier identifier = new BerIdentifier(BerIdentifier.UNIVERSAL_CLASS, 
     BerIdentifier.PRIMITIVE, BerIdentifier.ENUMERATED_TAG); 

有什麼我需要做的就是jASN1與自動標記工作,或者我需要一個不同的庫?如果是後者,人們推薦什麼?理想情況下,我正在尋找易於使用的開源Java解決方案。我想我可以做一個C解決方案,並使用JNI來實現它。

回答

1

這是一個非常骯髒的黑客讓jASN1使用自動標籤。這不是一個通用的解決方案,需要花費很多時間手動編輯所有生成的類,所以我仍然在尋找一個完整的解決方案。

生成的類內用於在該方法的不同的序列:

public int decode(InputStream is, boolean explicit) throws IOException { 

你會看到一些像這樣的代碼,其檢查所述標記/標識符:

if (berIdentifier.equals(MsgCount.identifier)) { 
     msgCnt = new MsgCount(); 
     subCodeLength += msgCnt.decode(is, false); 
     subCodeLength += berIdentifier.decode(is); 
    } 
    else { 
     throw new IOException("Identifier does not match the mandatory sequence element identifer."); 
    } 

的拋出異常因爲標識符不匹配。生成的類通常期望一個ASN Universal類,標記號是通用類型之一或類似構造的序列。您可以快速看到打印出來的解碼標識符和期望標識符的差異:

System.out.println("Decoded: " + berIdentifier + ", expected: " + MsgCount.identifier); 

可以因此然後強制預期標識設置爲自動標籤正確,設置類是CONTEXT_CLASS,最後整數位號,T是該領域的序列索引:

BerIdentifier identifier2 = new BerIdentifier(BerIdentifier.CONTEXT_CLASS, BerIdentifier.PRIMITIVE, 2); // Hardcode the true idenifier 
if (berIdentifier.equals(identifier2)) { // Check the decoded identifier matches our hard-coded value, instead of the generated 
     msgCnt = new MsgCount(); 
     ... // Carry on as before 

一些注意事項:在一個大的協議,它需要大量的時間去完成所有相關的解碼步驟。這很容易出錯。對協議的更改需要重新生成類併合並更改,這將會很痛苦。以上都不涉及編碼。我沒有完全測試一切,但我確信這是唯一需要的改變。

所以是的,請繼續發佈任何建議,但我希望以上對於真正卡住並需要快速入侵的任何人都很有用。

1

自1.6.0版本以來,jASN1支持自動標記。