ASN1標準對OID的編碼

2021-08-25 07:41:26 字數 1628 閱讀 5239

asn1對oid的編碼有一些規定,形如a.b.c.d.e的oid被編碼的時候,完全可以按照der的編碼規則將整個oid的型別設定為object,然後將每乙個點分數字的型別設定為integer,最終編碼為[obj|length[[int|lena[a]]][int|lenb[b]][int|lenc[c]]...],可是asn1標準並沒有如此編碼,而是使用了"more bit"這種方式,這樣就少了很多的層次,不必為每乙個點分數字進行asn1編碼,具體說來就是將乙個點分數字拆分為7bit一組的序列,然後除了最後乙個的最高位填入0之外其餘的最高位都填1,然後將它們合併在一起,最終將每乙個經過這樣處理的點分數字連線在一起,可以減少編碼的長度,起碼每個點分數字的type和length都省略了,唯一的不足是8bit的點分數字要編碼為16bits。

以上僅僅是對oid編碼的規定之一,還有乙個很有意思的就是由於oid的前兩極的標識數字都不是很大,因此更好的辦法就是將oid的前兩級編碼到乙個7bit的數中(由於標識more bit需要最高位,所以只剩下7位可以存資料),第一級oid只有3個,分別是itu-t(0),iso(1),joint-iso-itu-t(2),並且第二級oid標識最多也就23,掛於joint-iso-itu-t之下,現在需要乙個演算法,將第一級和第二級的oid標識編碼到乙個7bit的數裡面,這就需要用一種平坦的方式來索引前兩級的資料,構造一組虛擬的標識,為了對待三個一級oid標識更公平,最好是將127個「位置」平均分到三個一級標識,於是就將127除以3,結果是40,於是頭40個虛擬標識分給itu-t,中間40個分給iso,後面的47個分給joint-iso-itu-t,這樣,前兩級是a.b的oid的a和b就被編碼成了40*a+b,如此也就節省了乙個編碼byte。本質上這種編碼的思想是在分級的標識上構造一組平坦的虛擬標識。

實際上為何不採用x86的頁表的形式(或者說是trie樹的形式)來進行編碼呢,將127,也就是7個bit分成3個段,0-x為第一級索引,x+1-6位第二級索引...事實上這個想法是很不錯的,但是看一下真實的情況,由於第二級最大的oid標識數是23,二進位制為10111,又因為只能使用7個bit,則唯一的方案就是0-1bit為第一級索引,2-6bit為第二級索引,5個bit最大只能表示32,因此joint-iso-itu-t下還剩下9個可用的位置,雖然說root下面還有乙個位置,而該位置下能掛32個二級位置,但是oid是國際機構的人定義的,這就存在很大的不穩定性,雖說7bit數能包容的總的虛擬位置是一定的,但是怎樣對應這些平坦虛擬位置的真實分級位置卻存在很大的人為因素,在root下增加乙個節點的可能性不大,那意味的乙個新的頂級機構的產生,但是在已經存在的機構下產生乙個分支卻是正常的,故joint-iso-itu-t下增加新節點的可能性要比root下增加新節點的可能性大得多,asn1的編碼方案為joint-iso-itu-t留下了11個空閒位置,而類似trie樹的編碼方案只留下了確定的9個位置,孰優孰劣?看看同樣都是二級標識,joint-iso-itu-t下面有23個節點,而itu-t下面卻只有3個,然後就知道這樣人為因素很大的系統是多麼不適合在計算機中普遍使用的trie樹了,trie樹在不平衡的時候可以平衡化調整,可是oid樹能調整嗎?...

下面的perl**展示了oid的編碼過程:

sub der_it

push(@r,((($t++)?0x80:0)|$_));

$ret.=pack("c*",reverse(@r));

}return($ret);

}

asn1學習筆記 約束

繼續看asn1語法詳解,今天主要看了約束部分,包含 1.單值約束,包含列舉型別 enumerated 如 two integer 2 day enumerated wendnesday day wednesday after ia5string aaaaaa 2.型別包含約束 frenchweeke...

使用ASN 1協議編碼

在不同裝置節點進行通訊的時候,通常要定義乙個資料協議,用來定義要傳輸資料的資訊結構。而asn.1就是定義資料協議的一種方法。即寫乙個檔案,字尾名為 asn 例如 寫乙個檔案,檔案名叫 data.asn 檔案內容為 people sequence 即定義乙個資料結構people,包含兩個成員,乙個為位...

asn1學習筆記 約束

繼續看asn1語法詳解,今天主要看了約束部分,包含 1.單值約束,包含列舉型別 enumerated 如 two integer 2 day enumerated monday 0 tuesday 1 wednesday 2 thursday 3 friday 4 saturday 5 sunday...