asn.1

ASN.1 & OPTIONAL


From what I understood, ASN.1 UPER encoding packs the encoded data as efficient as possible.

Using asn1scc I compiled this into c-code:

HelloWorld DEFINITIONS ::= BEGIN
    DataItems ::= SEQUENCE (SIZE (0..1024)) OF DataItem

    DataItem ::= SEQUENCE {
        name IA5String (SIZE (0..32)) OPTIONAL,
        address IA5String (SIZE (0..256)) OPTIONAL
    }

END

I thought that making a field OPTIONAL it would only consume the full space when it was enabled or else only 1 bit. Also if I would have a DataItems sequence of only 3 items, then that it would use less space than the full 1024 items. Instead, instantiating the example above uses 260226 bytes!

Is there a way using ASN.1 to create smaller outputs?


Solution

  • First, note that your specification is not valid ... you must add AUTOMATIC TAGS

    HelloWorld DEFINITIONS AUTOMATIC TAGS ::= BEGIN
        DataItems ::= SEQUENCE (SIZE (0..1024)) OF DataItem
    
        DataItem ::= SEQUENCE {
            name IA5String (SIZE (0..32)) OPTIONAL,
            address IA5String (SIZE (0..256)) OPTIONAL
        }
    
    END
    

    The reason is you cannot tell the difference between name and address when you decode (as they are both optional).

    As for your question, the resource I use to get a quick answer is https://asn1.io/asn1playground/

    A few examples:

    value DataItems ::= {
    { name "one" },
    { name "two" },
    { name "three" }
    }  
    -- Encoded successfully in 14 bytes:
    -- 00707BF7 6583E9DF 7C2F4D1C B2E5
    
    value DataItems ::= {
    { name "one", address "one" },
    { name "two", address "two" },
    { name "three", address "three" }
    }
    -- Encoded successfully in 27 bytes:
    -- 00787BF7 6501EFDD 970FA77D E03E9DF7 E2F4D1CB 2E502F4D 1CB2E5