青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

無我

讓內(nèi)心永遠(yuǎn)燃燒著偉大的光明的精神之火!
靈活的思考,嚴(yán)謹(jǐn)?shù)膶?shí)現(xiàn)
豪邁的氣魄、頑強(qiáng)的意志和周全的思考

eSNACC對OBJECT IDENTIFIER的編碼和解碼

本文剖析asn-oid.h/c,從源代碼來學(xué)習(xí)eSNACC對OBJECT IDENTIFIER的編碼和解碼。

在研究代碼之前,我們先來說明什么是OBJECT IDENTIFIER。

————————————以下一段來自于http://www.eccsdk.com/bbs/read.php?tid=1772————————————————

 ASN.1 對象標(biāo)識符類型 
      對象標(biāo)識符(OBJECT IDENTIFIER, OID)類型用層次的形式來表示標(biāo)準(zhǔn)規(guī)范.標(biāo)識符樹通過一個(gè)點(diǎn)分的十進(jìn)制符號來定義,這個(gè)符號以組織,子部分然后是標(biāo)準(zhǔn)的類型和各自的子標(biāo)識符開始. 

      例如:MD5的OID 是 1.2.840.113549.2.5  表示為"iso(1) member-body (2) US (840) rsadsi(113549) digestAlgorithm (2) md5 (5)", 所以當(dāng)解碼程序看到這個(gè)OID時(shí),就知道是MD5散列. 

      OID在公鑰算法標(biāo)準(zhǔn)中很流行,它指出證書綁定了哪種散列算法. 同樣,也有公鑰算法,分組算法,和操作模式的OID. 它們是一種高效且可移植的表示數(shù)據(jù)包中所選算法的形式. 

      對OID的編碼規(guī)則: 
1、前兩部分如果定義為x.y, 那么它們將合成一個(gè)字40*x + y, 其余部分單獨(dú)作為一個(gè)字節(jié)進(jìn)行編碼. 
2、每個(gè)字首先被分割為最少數(shù)量的沒有頭零數(shù)字的7位數(shù)字.這些數(shù)字以big-endian格式進(jìn)行組織,并且一個(gè)接一個(gè)地組合成字節(jié). 除了編碼的最后一個(gè)字節(jié)外,其他所有字節(jié)的最高位(位8)都為1.
     舉例: 30331 = 1 * 128^2 + 108 * 128 + 123  分割成7位數(shù)字(0x80)后為{1,108,123}設(shè)置最高位后變成{129,236,123}.如果該字只有一個(gè)7位數(shù)字,那么最高為0.   

     MD5 OID的編碼: 
        1. 將1.2.840.113549.2.5轉(zhuǎn)換成字?jǐn)?shù)組 {42, 840, 113549, 2, 5}. 
        2. 然后將每個(gè)字分割為帶有最高位的7位數(shù)字,{{0x2A},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}. 
        3. 最后完整的編碼為 0x06 08 2A 86 48 86 F7 0D 02 05.

————————————————————————————————————————————————————————————

有了上面的直觀的理解,我們再研究代碼就不會(huì)困惑了。

在eSNACC中,OBJECT IDENTIFIER實(shí)現(xiàn)分為oid和RELATIVE OID。oid要求至少必須由兩部分?jǐn)?shù)字組成,因?yàn)橐幋a的一個(gè)值為40*x + y,所以如果不滿足就會(huì)報(bào)錯(cuò)。就如同上面例子中的MD5 OID,就有6個(gè)部分。而RELATIVE OID就沒有這個(gè)要求,對她的編碼沒有做40*x + y的操作,解碼也不需要逆處理。但是RELATIVE OID必須和一個(gè)oid根相關(guān)聯(lián)。因?yàn)?span style="font-family: 'Times New Roman'; font-size: 12pt; mso-fareast-font-family: 宋體; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">RELATIVE OID的定義方式和處理函數(shù)都與oid類似,僅僅是少了上面所說的第一個(gè)編碼規(guī)則操作,所以我們只討論oid,而RELATIVE OID就不展開了。

eSNACC對oid有兩種實(shí)現(xiàn):用字節(jié)串存放和用鏈表形式存放,對字節(jié)串存放,就是每一個(gè)字節(jié)存放一個(gè)數(shù)值;而鏈表,就是每一個(gè)節(jié)點(diǎn)元素存放一個(gè)值。不過文檔說:如果追求更好的性能,應(yīng)當(dāng)采用字節(jié)串的形式。這兩種方式定義如下:

字節(jié)串形式,定義為AsnOid,直接從AsnOcts定義過來:

typedef AsnOcts AsnOid;  /* standard oid type  */

鏈表形式,定義為OID:

/* linked oid type that may be easier to use in some circumstances */
#define NULL_OID_ARCNUM    -1
typedef 
struct OID
{
  
struct OID    *next;
  
long arcNum;
#if COMPILER || TTBL
  
struct Value    *valueRef;
#endif
}
 OID;

頭文件中還定義了若干函數(shù)實(shí)現(xiàn)這兩者的互相轉(zhuǎn)換。

嚴(yán)重說明:

AsnOid存放的是已經(jīng)對原始的OBJECT IDENTIFIER編碼之后的值!比如上面例子的MD5,字節(jié)串是2A 86 48 86 F7 0D 02 05。

而OID存的是OBJECT IDENTIFIER的原始值鏈。比如上面例子的MD5,鏈表為1->2->840->113549->2->5。

 

 

/**************************************休息一下********************************************

上文我們說過:AsnOid存放的是已經(jīng)對原始的OBJECT IDENTIFIER編碼之后的值。所以我們當(dāng)我們要對一個(gè)AsnOid進(jìn)行打印輸出時(shí),就需要進(jìn)行前面所說編碼算法的逆運(yùn)算,這個(gè)我們可以通過打印例程來驗(yàn)證一下:

/*
 * Prints the given OID to the given FILE * in ASN.1 Value Notation.
 * Since the internal rep of an OID is 'encoded', this routine
 * decodes each individual arc number to print it.
 
*/

void
PrintAsnOid PARAMS ((f,v, indent),
    FILE 
*f _AND_
    AsnOid 
*v _AND_
    unsigned 
int indent)
{
    unsigned 
int firstArcNum;
    unsigned 
int arcNum;
    
int i;

    fprintf (f,
"{");

    
/* un-munge first two arc numbers */
    
for (arcNum = 0, i=0; (i < (int)(v->octetLen)) && (v->octs[i] & 0x80);i++)
        arcNum 
= (arcNum << 7+ (v->octs[i] & 0x7f);

    arcNum 
= (arcNum << 7+ (v->octs[i] & 0x7f);
    i
++;
    firstArcNum 
= (unsigned short)(arcNum/40);
    
if (firstArcNum > 2)
        firstArcNum 
= 2;

    fprintf (f,
"%u %u", (unsigned int)firstArcNum, arcNum - (firstArcNum * 40));

    
for (; i < (int)(v->octetLen); )
    
{
        
for (arcNum = 0; (i < (int)(v->octetLen)) && (v->octs[i] & 0x80);i++)
            arcNum 
= (arcNum << 7+ (v->octs[i] & 0x7f);

        arcNum 
= (arcNum << 7+ (v->octs[i] & 0x7f);
        i
++;
        fprintf (f,
" %u", arcNum);
    }

    fprintf (f,
"}");
    indent
=indent; /* referenced to avoid compiler warning. */

}
 /* PrintAsnOid */

從代碼可以看到,這個(gè)算法就是這樣的:

首先得到第一個(gè)數(shù),因?yàn)槿绻粋€(gè)編碼后的數(shù)用了多個(gè)字節(jié)表示,那么除了最后一個(gè)以外,前面的字節(jié)的最高位肯定為1.所以就用一個(gè)循環(huán)來獲取一個(gè)完整的數(shù)。后面嵌套的for也是這個(gè)原理。然后對取得的第一個(gè)數(shù)分拆:num=first*40+second。這樣就完成第一步的逆算法并打印出來。

然后遍歷這個(gè)字節(jié)串,每獲取一個(gè)完整的數(shù)就打印出來。由于for循環(huán)只是把最高位為1的字節(jié)遍歷了,所以都需要加上最后一個(gè)字節(jié)。其實(shí)我們發(fā)現(xiàn)用多個(gè)字節(jié)存的數(shù)對應(yīng)前面的字節(jié)的128的n次方和最末尾一個(gè)字節(jié)值的和。

 

而OID存的是原始值,就讓我們通過這個(gè)OID -> AsnOid的函數(shù)來進(jìn)一步理解兩者的不同:

/*
 * given an oid list and a pre-allocated ENC_OID
 * (use EncodedOidLen to figure out byte length needed)
 * fills the ENC_OID with a BER encoded version
 * of the oid.
 
*/

void
BuildEncodedOid PARAMS ((oid, result),
    OID 
*oid _AND_
    AsnOid 
*result)
{
    unsigned 
long len;
    unsigned 
long headArcNum;
    unsigned 
long tmpArcNum;
    
char         *buf;
    
int           i;
    OID          
*tmpOid;

    buf 
= result->octs;
    
/*
     * oid must have at least 2 elmts
     
*/

    
if (oid->next == NULL)
       
return;
    
/*
     * munge together first two arcNum
     * note first arcnum must be <= 2
     * and second must be < 39 if first = 0 or 1
     * see (X.209) for ref to this stupidity
     
*/

    
//head = first * 40 + second
    headArcNum = (oid->arcNum * 40+ oid->next->arcNum;
    tmpArcNum 
= headArcNum;

    
/*
     * 計(jì)算存放第一個(gè)數(shù)需要幾個(gè)字節(jié)。每7位要一個(gè)字節(jié)
     
*/

    
for (len = 0; (tmpArcNum >>= 7!= 0; len++)
    ;

    
/*
     * 從高位到低位,把每7位寫到緩沖區(qū),因?yàn)椴皇亲詈笠粋€(gè)字節(jié),所以都把最高位設(shè)為1
     
*/

    
for (i=0; i < (int)len; i++)
        
*(buf++= (char)(0x80 | (headArcNum >> ((len-i)*7)));

    
/*
     * 將寫第一個(gè)數(shù)的最后7位寫到最后一個(gè)字節(jié)
     
*/

    
*(buf++= (char)(0x7f & headArcNum);


    
/*
     * 如果有,就把后面的數(shù)寫到緩沖區(qū),原理和第一個(gè)數(shù)相同,里面不再注釋
     
*/

    
for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
    
{
        tmpArcNum 
= tmpOid->arcNum;
        
for (len = 0; (tmpArcNum >>= 7!= 0; len++)
        ;

        
for (i=0; i < (int)len; i++)
            
*(buf++= (char)(0x80 | (tmpOid->arcNum >> ((len-i)*7)));

          
*(buf++= (char)(0x7f & tmpOid->arcNum);
    }

    result
->octetLen = (buf - result->octs);//根據(jù)被寫的緩沖區(qū)設(shè)定字節(jié)長度
}
 /* BuildEncodedOid */

在上面的函數(shù)中,我已經(jīng)對相應(yīng)語句做了注釋了,所以這里就不復(fù)述了。

 

文件中其他函數(shù)都是這個(gè)原理,就很簡單了。本篇就到此吧。

posted on 2012-04-24 16:30 Tim 閱讀(1836) 評論(0)  編輯 收藏 引用 所屬分類: eSNACC學(xué)習(xí)

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導(dǎo)航

統(tǒng)計(jì)

公告

本博客原創(chuàng)文章,歡迎轉(zhuǎn)載和交流。不過請注明以下信息:
作者:TimWu
郵箱:timfly@yeah.net
來源:www.shnenglu.com/Tim
感謝您對我的支持!

留言簿(9)

隨筆分類(173)

IT

Life

搜索

積分與排名

最新隨筆

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品夜色噜噜亚洲aⅴ| 国产精品综合| 久久米奇亚洲| 国产麻豆成人精品| 欧美激情一区二区三区在线| 狠狠爱成人网| 免费不卡亚洲欧美| 亚洲国产精品成人一区二区 | 欧美全黄视频| 亚洲精品视频啊美女在线直播| 激情小说亚洲一区| 欧美久久婷婷综合色| 亚洲免费激情| 久久天堂精品| 亚洲国产精品一区二区久| 欧美.com| 一区二区精品国产| 久久亚洲影院| 亚洲午夜视频| 国产在线精品一区二区夜色| 久久久久国产精品一区三寸| 日韩网站在线| 欧美电影在线免费观看网站| 亚洲第一色中文字幕| 欧美国产一区二区在线观看 | 亚洲一区二区网站| 国产精品手机在线| 欧美黄色小视频| 亚洲一级黄色片| 免费视频一区二区三区在线观看| 中文欧美字幕免费| 久久蜜桃av一区精品变态类天堂| 欧美精品一区二区精品网| 玖玖视频精品| 亚久久调教视频| 亚洲国产一区二区三区青草影视 | 一区二区激情视频| 美日韩精品视频免费看| 久久福利毛片| 久久精品免费| 久久综合给合久久狠狠狠97色69| 亚洲综合欧美日韩| 亚洲天堂av在线免费| 一本色道精品久久一区二区三区 | 国产亚洲欧洲997久久综合| 国模私拍一区二区三区| 亚洲一区网站| 欧美香蕉视频| 午夜视频一区二区| 亚洲深夜福利| 亚洲一区免费| 午夜精品久久久久久久久久久| 一区二区不卡在线视频 午夜欧美不卡'| 欧美成人视屏| 亚洲国产高清一区| 亚洲电影视频在线| 亚洲精品资源| 亚洲欧美日韩网| 久久先锋资源| 国产精品网站视频| 亚洲欧美综合精品久久成人| 樱桃成人精品视频在线播放| 精品二区久久| 99在线精品视频在线观看| 亚洲欧美综合一区| 国产精品久久久久影院色老大 | 亚洲自拍另类| 欧美一级免费视频| 亚洲欧美在线一区二区| 夜夜狂射影院欧美极品| 欧美日韩精品三区| 一本大道久久a久久精二百| 在线视频亚洲欧美| 欧美成人资源| 欧美激情偷拍| 欧美激情中文字幕一区二区 | 一区二区三区四区在线| 亚洲国产成人91精品| 激情五月***国产精品| 国内成+人亚洲+欧美+综合在线| 国产一区二区三区在线免费观看 | 一区在线视频观看| 欧美 亚欧 日韩视频在线| 久久久久久久综合日本| 欧美精品一区二区三区四区| 欧美国产国产综合| 久久成人精品视频| 国产精品亚洲一区| 国产欧美日韩精品a在线观看| 一本久道久久久| 久久这里只有| 亚洲欧美日韩综合一区| 久久国产精品99国产精| 亚洲国产精品电影| 午夜视频久久久| 亚洲免费电影在线| 一区二区日韩伦理片| 亚洲国产精品成人综合| 在线亚洲免费视频| 美女免费视频一区| 小黄鸭精品密入口导航| 国产日韩在线不卡| 欧美成人综合网站| 国产日韩精品一区观看| 亚洲国产日日夜夜| 奶水喷射视频一区| 红桃视频亚洲| 欧美成人蜜桃| 中文欧美在线视频| 亚洲一区二区在| 国产欧美精品一区二区色综合| 亚洲网站视频福利| 欧美一区2区三区4区公司二百| 韩国av一区二区三区| 99国产精品久久| 欧美成人网在线| 亚洲欧洲日本国产| 国产欧美精品日韩精品| 亚洲久久视频| 欧美日韩中文字幕| 久久精品主播| 国产精自产拍久久久久久蜜| 麻豆91精品91久久久的内涵| 国产精品久久久一区二区三区| 免费不卡在线观看av| 国产精品中文在线| 91久久中文字幕| 亚洲国产小视频在线观看| 久久久99国产精品免费| 欧美在线免费视屏| 国产亚洲欧美日韩一区二区| 欧美一区在线直播| 亚洲免费成人| 亚洲欧美精品suv| 欧美日韩中文字幕| 亚洲美洲欧洲综合国产一区| 欧美激情第五页| 亚洲自拍16p| 99精品99久久久久久宅男| 久久免费国产精品| 亚洲国产精品www| 亚洲视频axxx| 午夜性色一区二区三区免费视频| 久热精品视频在线免费观看| 欧美亚洲一区二区在线| 卡通动漫国产精品| 久久久久成人精品| 国内精品久久久久伊人av| 欧美在线不卡视频| 99国产精品久久久久久久久久| 亚洲视频在线一区| 久久精品国产精品亚洲综合| 欧美亚洲日本一区| 欧美日韩精品二区| 91久久精品国产91久久性色tv| 在线日韩欧美| 久久久久.com| 亚洲免费大片| 国产亚洲成人一区| 久久黄色级2电影| 亚洲淫性视频| 亚洲国产美女精品久久久久∴| 亚洲欧美日韩一区二区在线 | 在线免费观看视频一区| 欧美人在线观看| 久久婷婷国产麻豆91天堂| 一区二区三区www| 美女视频黄a大片欧美| 亚洲综合999| 亚洲日韩欧美视频| 另类酷文…触手系列精品集v1小说| 亚洲精品一区二区三区四区高清 | 国产日韩欧美高清免费| 欧美日本国产一区| 蜜桃av久久久亚洲精品| 久久精品电影| 久久九九有精品国产23| 亚洲一级黄色片| 一本久久a久久精品亚洲| 最新国产拍偷乱拍精品| 亚洲第一网站| 91久久夜色精品国产九色| 久久精彩免费视频| 性做久久久久久免费观看欧美| 一区二区三区毛片| 午夜精品福利一区二区蜜股av| 欧美一级夜夜爽| 欧美成人69av| 日韩一级成人av| 久久精品亚洲| 欧美日韩在线精品一区二区三区| 国产精品久久久久影院色老大| 国产精品视频网址| 欧美日韩不卡一区| 欧美日韩久久不卡| 国产精品入口| 亚洲久久一区二区| 性色一区二区三区| 欧美va亚洲va日韩∨a综合色| 亚洲毛片在线观看|