利用開源ASN1C庫實現asn.1的編解碼(windows)


轉自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28765492&id=3765759

       最近在研究MMS的時候接觸到了抽象語義記法ASN.1(Abstract Syntax Notation One),於是對它做了一番了解,下面將這幾天的學習到的做下記錄,以供以后偷懶。
        ASN.1是一種 ISO/ITU-T 標准,描述了一種對數據進行表示、編碼、傳輸和解碼的數據格式。它提供了一整套正規的格式用於描述對象的結構,而不管語言上如何執行及這些數據的具體指 代,也不用去管到底是什么樣的應用程序,也就是說這種記法獨立於編程語言,具有平台無關性。關於它的更多的介紹百度文庫有很多資源,這里提供一個 ISO/ITU-T 標准關於本部分標准的鏈接,全英文看起來是吃力了點,但慢慢品讀下來往往會有想不到的收獲。(http://www.itu.int/ITU-T/recommendations/index.aspx),在search欄輸入x.680~x.683或x.690可以查看到ASN.1的具體標准及編解碼的方法,或者從http://www.itu.int/ITU-T/studygroups/com17/languages/獲得相關文檔。
        有了ASN.1和相關編碼的概念之后,接下來就是如何用編程語言實現ASN.1的編解碼了,下面結合開源編譯器ASN1C對這部分做詳細介紹。
       
        一、下載asn.1 編譯器ASN1C
                在http://lionet.info/asn1c/download.html處下載,此處我選擇了“Windows installer: asn1c-0.9.21.exe”,下載后雙擊安裝即可。
                本文假設安裝於“D:\Program Files\asn1c”。

        二、創建asn.1抽象模型並利用ASN1C編譯器生成C語言類型文件
                1、asn.1文本描述如下

點擊(此處)折疊或打開

  1. RetangleTest DEFINITIONS ::=BEGIN
  2.     Rectangle ::= SEQUENCE{
  3.         height INTEGER,        -- Height of the rectangle
  4.         width INTEGER        -- Width of the rectangle
  5.     }
  6. END

                    保存文件為“D:\Program Files\asn1c\try.asn1"。

                2、利用ASN1C工具生成try.asn1的C語言類型文件
                    假設ASN1C安裝在“D:\Program Files\asn1c”路徑下,可以按如下步驟生成C語言類型文件:
                    ①打開控制台:"開始-運行-cmd";
                    ②進入到軟件目錄下:cd “D:\Program Files\asn1c”;
                    ③執行生成指令:輸入asn1c -S skeletons -fskeletons-copy -fnative-types try.asn1+回車enter

                    其中-S -fskeletons-copy -fnative-types參數可以在“D:\Program Files\asn1c\Help\asn1c-usage.pdf”使用手冊查到相關說明。

                    若執行成功,則有如下信息輸出到控制台


                並可以看到在“D:\Program Files\asn1c”目錄下,增加了許多文件,這些文件都是后面要用到的:
                                    

        三、在VS2010中創建asn.1的編解碼demo工程
                1、創建win32 console工程asn1_demo
                2、將步驟二生成的所有.h和.c文件拷貝到asn1_demo工程文件夾下
                3、將.h和.c文件添加到工程中
                                       
                4、創建main.c文件,內容如下

點擊(此處)折疊或打開

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <Rectangle.h>

  4. char tab[8];
  5. /*
  6. * This is a custom function which writes the
  7. * encoded output into a global test table
  8. */
  9. static int decode_callback(const void *buffer, size_t size, void *app_key)
  10. {
  11.     static int i = 0;
  12.     
  13.     memcpy(&tab[i],buffer,size);

  14.     i += size;
  15. }



  16. int main()
  17. {
  18.     Rectangle_t *rectangle; /* Type to encode */
  19.     asn_enc_rval_t ec; /* Encoder return value */

  20.     /* Allocate the Rectangle_t */
  21.     rectangle = (Rectangle_t*)calloc(1, sizeof(Rectangle_t)); /* not */

  22.     if(!rectangle) {
  23.         perror("calloc() failed");
  24.         exit(71); /* better, EX_OSERR */
  25.     }

  26.     /* Initialize the Rectangle members */
  27.     rectangle->height = 42; /* any random value */
  28.     rectangle->width = 23; /* any random value */



  29.     /* Encode the Rectangle type as BER (DER) */
  30.     ec = der_encode(&asn_DEF_Rectangle,
  31.         rectangle, decode_callback, tab);

  32.     if(ec.encoded == -1) {
  33.         fprintf(stderr,
  34.             "Could not encode Rectangle (at %s)\n",
  35.             ec.failed_type ? ec.failed_type->name : "unknown");
  36.         exit(65); /* better, EX_DATAERR */
  37.     } else {
  38.         fprintf(stderr, "Created %s with BER encoded Rectangle\n",
  39.             "");
  40.     }

  41.     /* Also print the constructed Rectangle XER encoded (XML) */
  42.     xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
  43.     return 0;
  44. }

                5、移除converter-sample.c
                6、編譯,若出現頭文件找不到問題,在工程屬性的頭文件包含路徑下指定頭文件路徑即可。
                7、運行,將斷點設於最有一句"return 0"處,可看到控制台顯示如下,該xml格式的數據是55行執行的結果。
                     此時,觀察全局數組table,可以看到里面的內容即為Rectangle的編碼后的十六進制數據為 30 06 02 01 2a 02 01 17。



四、解碼
            解碼的example可查看用戶手冊“D:\Program Files\asn1c\Help\asn1c-usage.pdf”,和編碼example類似,這里不做贅述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM