English

ASN.1 C编译器使用入门

学习任何语言或标记的最好方法莫过于读它的例子。在本节中教程中,我们将引导您创建并运行一个简单的ASN.1应用。更多详细信息,请参阅ASN.1 C编译器用户指南。

安装ASN.1 C编译器

点击 这里 查看如何下载和安装的ASN.1 SDK和ASN.1 C编译器插件的说明。

设置License Key

申请一个试用License或从ASN Lab网站购买一个永久License。 在Eclipse中,选择Windows (在Mac机器, Eclipse) > Preferences > ASN.1 > ASN.1 C Compiler打开ASN.1 C Compiler首选项页面。在General section中输入License Key,然后点击 OK。

MyHTTP例子

MyHTTP例子改编自 http://www.w3.org/Protocols/HTTP-NG/asn1.html, 它是一个FHTTP GET请求的简化形式。 对于我们的例子,假设我们需要应用以下我们已经在ASN.1开发工具 使用入门中看到过的ASN.1模块。

  1. 选择 File > New > Project...
  2. ASN.1 类目中, 选择 ASN.1 Project, 然后点击 Next.
  3. 工程名输入 'MyHTTP' 然后点击 Finish.
  4. 现在ASN.1 文件可以添加到项目中,通过从其他地方复制到项目的源目录,或者按从以下步骤零开始创建ASN.1文件:
  5. 选择 File > New > Other...
  6. ASN.1 类目中, 选择 ASN.1 Module, 然后点击 Next.
  7. 模块名中输入 'MyHTTP' 然后点击Finish.
  8. 在开启的编辑器中输入以下的源代码:
    MyHTTP DEFINITIONS
    AUTOMATIC TAGS ::=
    BEGIN
    
       GetRequest ::= SEQUENCE {
          header-only   BOOLEAN,
          lock          BOOLEAN,
          accept-types  AcceptTypes,
          url           Url,
          ...,
          timestamp     GeneralizedTime
       }
    
       AcceptTypes ::= SET {
          standards   BIT STRING { html(0), plain-text(1), gif(2), jpeg(3) } (SIZE(4)) OPTIONAL,
          others      SEQUENCE OF VisibleString (SIZE(4)) OPTIONAL
       }
    
       Url ::= VisibleString (FROM("a".."z"|"A".."Z"|"0".."9"|"./-_~%#"))
    
       myRequest GetRequest ::= {
          header-only  TRUE,
          lock         FALSE,
          accept-types {
             standards { html, plain-text }
          },
          url          "www.asnlab.org",
          timestamp    "20121221121221Z"
       }
    
    END
  9. 保存 ASN.1 文件, 编译好的C数据结构文件将自动生成(如果没有,请检查License Key是否设置好)。
  10. 创建一个test.c文件,输入如下内容:
    #include "stdio.h"
    #include "stdlib.h"
    #include "stdarg.h"
    #include "GetRequest.h"
    
    static int print(AsnPrinter* printer, const char* __format, ...);
    
    AsnPrinter printer = { 0, print };
    
    int main(void) {
       int result;
    
       char bytes[1] = { 0xC0 };
       Bits standards = { 4, bytes };
       struct GetRequest myRequest = {
          true /* header_only */,
          false /* lock */,
          {
             &standards /* standards */,
             NULL /* others */
          } /* accept_types */,
          "www.asnlab.org" /* url */,
          { 2012, 12, 21, 12, 12, 21, 0, 0, 0 } /* timestamp */
       };
    
       /*
        * Allocate the memory for the buffer
        */
       AsnBuffer* buffer = alloc_buffer(160, true, BASIC_ENCODING_RULES);
    
       /*
        * Do the encoding
        */
       result = encode_GetRequest(buffer, &myRequest);
    
       if(result==0) {
          /*
           * Print out the content of the buffer
           */
          int i;
          for(i=0; i<buffer->limit; i++) {
             char byte = buffer->array[i];
             printf("%02X ", byte & 0xFF);
          }
       }
       else {
          fprintf(stderr, "Error in encoding, error code: %d.\n", result);
          print_problem_marks(buffer, &myRequest, &GETREQUEST_TYPE, &printer);
       }
    
       /*
        * Deallocate the memory for the buffer
        */
       free_buffer(buffer);
    
       return 0;
    }
    
    static int print(AsnPrinter* printer, const char* __format, ...) {
       va_list arg_ptr;
       int cnt;
       va_start(arg_ptr, __format);
       cnt = vprintf(__format, arg_ptr);
       va_end(arg_ptr);
       return cnt;
    }
  11. 复制运行库和头文件(从ASN.1 C运行库包解压)到编译产生文件的目录。
  12. 编译所有.c文件:

    $ gcc -c *.c

  13. 连接.o文件和运行库:

    $ gcc -o test *.o -L. -lasnrt

  14. 运行:

    $ ./test
    30 2D 80 01 FF 81 01 00 A2 04 80 02 04 C0 83 0E 77 77 77 2E 61 73 6E 6C 61 62 2E 6F 72 67 84 0F 32 30 31 32 31 32 32 31 31 32 31 32 32 31 5A

BER编码后的逐字节逐比特的含义:

0x30 -- [0011|0000], [UNIVERSAL, CONSTRUCTED, 16(SEQUENCE)] - GetRequest
0x2D -- [0010|1101], length 45

0x80 -- [1000|0000], [CONTEXT, PRIMITIVE, 0(BOOLEAN)] GetRequest.header_only
0x01 -- [0000|0001], length 1
0xFF -- [0000|1111], value TRUE

0x81 -- [1000|0001], [CONTEXT, PRIMITIVE, 1(BOOLEAN)] GetRequest.lock
0x01 -- [0000|0001], length 1
0x00 -- [0000|0000], value FALSE

0xA2 -- [1010|0010], [CONTEXT, CONSTRUCTED, 2(SET)] - GetRequest.accept_types
0x04 -- [0000|0100], length 4

0x80 -- [1000|0000], [CONTEXT, PRIMITIVE, 0(BIT STRING)] AcceptTypes.standards
0x02 -- [0000|0010], length 2
0x04 -- [0000|0100], 4 unused bits
0xC0 -- [1100|0000], {html, plaint_text}

0x83 -- [1000|0011], [CONTEXT, PRIMITIVE, 3(VisibleString)] GetRequest.url
0x0E -- [0000|1100], length 14
0x77 0x77 0x77 0x2E 0x61 0x73 0x6E 0x6C 0x61 0x62 0x2E 0x6F 0x72 0x67 -- www.asnlab.org

0x84 -- [1000|0011], [CONTEXT, PRIMITIVE, 4(GeneralizedTime)] GetRequest.timestamp
0x0F -- [0000|1100], length 15
0x32 0x30 0x31 0x32 0x31 0x32 0x32 0x31 0x31 0x32 0x31 0x32 0x32 0x31 0x5A -- 20121221121221Z

更多信息

关于ASN.1 C运行库的更多信息, 请参阅ASN.1 C运行库用户指导