学习任何语言或标记的最好方法莫过于读它的例子。在本节中教程中,我们将引导您创建并运行一个简单的ASN.1应用。更多详细信息,请参阅ASN.1 C编译器用户指南。
点击 这里 查看如何下载和安装的ASN.1 SDK和ASN.1 C编译器插件的说明。
申请一个试用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
例子改编自
http://www.w3.org/Protocols/HTTP-NG/asn1.html,
它是一个FHTTP GET请求的简化形式。
对于我们的例子,假设我们需要应用以下我们已经在ASN.1开发工具
使用入门中看到过的ASN.1模块。
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
#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; }
$ gcc -c *.c
$ gcc -o test *.o -L. -lasnrt
$ ./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运行库用户指导。