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?
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