TOP

ASN.1 Made Simple — Example


This example illustrates how ASN.1 can be used to structure and validate real-world data.

Suppose we want to define a Purchase Order for electronic exchange. It contains a date, customer information, a list of items purchased, etc.

Purchase Order Example in ASN.1
MyShopPurchaseOrders DEFINITIONS AUTOMATIC TAGS ::= BEGIN

PurchaseOrder ::= SEQUENCE {
    dateOfOrder DATE,
    customer    CustomerInfo,
    items       ListOfItems
}
Defining the Components
CustomerInfo ::= SEQUENCE {
    companyName    VisibleString (SIZE (3..50)),
    billingAddress Address,
    contactPhone   NumericString (SIZE (7..12))
}


Address ::= SEQUENCE {
    street  VisibleString (SIZE (5..50)) OPTIONAL,
    city    VisibleString (SIZE (2..30)),
    state   VisibleString (SIZE(2) ^ FROM ("A".."Z")),
    zipCode NumericString (SIZE(5 | 9))
}

ListOfItems ::= SEQUENCE (SIZE(1..100)) OF Item

Item ::= SEQUENCE {
    itemCode        INTEGER (1..99999),
    color           VisibleString ("Black" | "Blue" | "Brown"),
    power           INTEGER (110 | 220),
    deliveryTime    INTEGER (8..12 | 14..19),
    quantity        INTEGER (1..1000),
    unitPrice       REAL (1.00 .. 9999.00),
    isTaxable       BOOLEAN
}
END
Naming conventions
  • Module and Type names (such as PurchaseOrder) begin with uppercase letters
  • Field names (such as dateOfOrder) begin with lowercase letters

Constraints

Constraints restrict the allowed values in a type, enabling validation and compact encoding.

Constraint Type Example
Single value constraint color VisibleString ("Black" | "Blue" | "Brown")
power INTEGER (110 | 220)
Value range quantity INTEGER (1..1000)
deliveryTime INTEGER (8..12 | 14..19)
unitPrice REAL (1.00..9999.00)
State ::= VisibleString SIZE(2) ^ FROM ("A".."Z"))
Size constraint contactPhone NumericString (SIZE (7..12))
ListOfItems ::= SEQUENCE (SIZE (1..100)) OF Item
zipCode NumericString (SIZE (5 | 9))

Modules and Tags

Module Organization

All ASN.1 definitions are placed inside a module, starting with BEGIN and ending with END.

AUTOMATIC TAGS

Automatically assigns unique tags internally, avoiding ambiguity and improving readability.

Address ::= SEQUENCE {
    street  [0] VisibleString (SIZE (5..50)) OPTIONAL,
    city    [1] VisibleString (SIZE (2..30)),
    state   [2] VisibleString (SIZE(2) ^ FROM ("A".."Z")),
    zipCode [3] NumericString (SIZE(5 | 9))
}

Since all tags are unique, there is no difficulty determining which values are present or absent in a message, and which components those values are for (e.g. during the decoding process).

IMPORTS

Used when referencing definitions from another module. The imported item can be used as if it was defined locally in the module.

MyShopPurchaseOrders DEFINITIONS AUTOMATIC TAGS ::= BEGIN
IMPORTS Address FROM PostalInformation;

JSON to ASN.1 Example

This example shows how a simple JSON message can be described with ASN.1, first using a generic schema, and then refining it with constraints.

{
  "itemCode": 10234,
  "color": "Brown",
  "power": 110,
  "deliveryTime": 12,
  "quantity": 2,
  "unitPrice": 4.99,
  "isTaxable": true
}

A generic ASN.1 schema auto-generated using JSON2ASN might look like:

GeneratedType ::= SEQUENCE {
    itemCode     INTEGER,
    color        UTF8String,
    power        INTEGER,
    deliveryTime INTEGER,
    quantity     INTEGER,
    unitPrice    REAL,
    isTaxable    BOOLEAN
}

Using ASN.1 and constraints, you can refine this into a more precise type, such as the Item definition used earlier:

Item ::= SEQUENCE {
    itemCode     INTEGER (1..99999),
    color        VisibleString ("Black" | "Blue" | "Brown"),
    power        INTEGER (110 | 220),
    deliveryTime INTEGER (8..12 | 14..19),
    quantity     INTEGER (1..1000),
    unitPrice    REAL (1.00 .. 9999.00),
    isTaxable    BOOLEAN
}
Next Steps
  • Try encoding this example using different encoding rules (BER, DER, CER, PER, OER, XER, JSON) in the ASN.1 Playground.
Related Topics