SNMP ASN.1 OID編碼規則

SNMP ASN.1 OID編碼規則
對象標識符(OBJECT IDENTIFIER, OID) 的編碼規則
對象標識符類型
對象標識符(OBJECT IDENTIFIER, OID)類型用層次的形式來表示標準規範.標識符樹通過一個點分的十進制符號來定義,這個符號以組織,子部分然後是標準的類型和各自的子標識符開始.
例如:MD5的OID 是 1.2.840.113549.2.5 表示爲"iso(1) member-body (2) US (840) rsadsi(113549) digestAlgorithm (2) md5 (5)", 所以當解碼程序看到這個OID時,就知道是MD5散列.
OID在公鑰算法標準中很流行,它指出證書綁定了哪種散列算法. 同樣,也有公鑰算法,分組算法,和操作模式的OID. 它們是一種高效且可移植的表示數據包中所選算法的形式.
對OID的編碼規則:
前兩部分如果定義爲x.y, 那麼它們將合成一個字40*x + y, 其餘部分單獨作爲一個字節進行編碼.
每個字首先被分割爲最少數量的沒有頭零數字的7位數字.這些數字以big-endian格式進行組織,並且一個接一個地組合成字節. 除了編碼的最後一個字節外,其他所有字節的最高位(位8)都爲1.
舉例: 30331 = 1 * 128^2 + 108 * 128 + 123 分割成7位數字(0x80)後爲{1,108,123}設置最高位後變成{129,236,123}.如果該字只有一個7位數字,那麼最高爲0.
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。本質上這種編碼的思想是在分級的標識上構造一組平坦的虛擬標識。
實例說明:
CPU空閒值的OID爲:1.3.6.1.4.1.2011.11.11.0
其編碼後爲 2b 06 01 04 01 8f 65 0b 0b 00
編碼原因:
ISO規定前兩級格式爲:第一級 * 40 + 第二級,即爲 1*40 + 3 = 43,十六進制爲 2b.
後面小於128的直接轉換
.6.1.4.1.2011.11.11.0
06 01 04 01 (2011) 0b 0b 00
2011轉化爲15*128 + 101,爲 (15,101),
15最高位置爲1,爲15+128=143,101最高位不變,爲(143,101)
十六進制爲 8f 65
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章