ASN.1 Packed Encoding Rules (PER) UNALIGNED variant

Introduction

This article briefly summarizes the ASN.1 Packed Encoding Rules (PER) UNALIGNED variant used in the 3GPP specifications with examples.

Disclaimer

This is a simplified explanation and not a complete specification. Missing examples used in the 3GPP specifications will be updated as soon as possible.

Encoding rules

Length determinant

If length determinant len is to be encoded as Constrained whole number with lower bound lb and upper bound ub less than 64K (65,536):

  • If range (ub - lb + 1) is equal to 1, no bits are used for length determinant.
  • Otherwise, minimum number of bits to represent ub - lb are used and len - lb is encoded like ‘unsigned integer’ in other languages.
    1
    2
    3
    4
    bit n        1
    +----------+
    | len - lb |
    +----------+

If length determinant len is to be encoded as Normally small length, a single bit indicating whether the value is less than or equal to 64 is inserted and the value is encoded in two ways:

  • If the value is less than or equal to 64, the bit is set to 0 and len - 1 is encoded like 6-bit ‘unsigned integer’ in other languages.
    1
    2
    3
    4
    bit   6       1
    +-+---------+
    |0| len - 1 |
    +-+---------+
  • Otherwise, the bit is set to 1 and the value is encoded as described below.
    1
    2
    3
    +-+------+
    |1| len* |
    +-+------+

If length determinant len is unconstrained or semi-constrained and less than or equal to 127, a single bit 0 is inserted and the value is encoded as 7-bit ‘unsigned integer’ in other languages.

1
2
3
4
bit   7   1
+-+-----+
|0| len |
+-+-----+

If length determinant len is unconstrained or semi-constrained and larger than or equal to 127 and less than 16K (16,384), two bits 10 are inserted and the value is encoded as 14-bit ‘unsigned integer’ in other languages.

1
2
3
4
bit    14  1
+--+-----+
|10| len |
+--+-----+

If length determinant len is unconstrained or semi-constrained and larger than 16K, len is divided into A 64K + B 16K + C. Two bits 11, 000100 and 64K items are inserted and they are repeated A times. If 16K or more items remain, two bits 11, 000001/000010/000011 and corresponding number of items are inserted. Finally, unconstrained or semi-constrained length determinant is inserted and remaining items are inserted.

1
2
3
4
5
6
7
8
9
+--+--------+-------+--+---------+-------+-+-----+----------------+
|11| 000100 | items |11| len (B) | items |0| len | items (<= 127) |
+--+--------+-------+--+---------+-------+-+-----+----------------+
^-A repetition----^ ^-0/1 repetition---^

+--+--------+-------+--+---------+-------+--+-----+-------------------------+
|11| 000100 | items |11| len (B) | items |10| len | items (> 127 and < 16K) |
+--+--------+-------+--+---------+-------+--+-----+-------------------------+
^-A repetition----^ ^-0/1 repetition---^

Boolean type

BOOLEAN
A single bit is set to 1 for TRUE and 0 for FALSE

1
2
3
4
bit 1
+-+
|b|
+-+

Integer type

INTEGER (lb..ub)
Minimum number of bits to represent ub - lb are used and value - lb is encoded like ‘unsigned integer’ in other languages.

1
2
3
4
bit n          1
+------------+
| value - lb |
+------------+

INTEGER (lb..ub, ...)
A single bit indicating whether the value is not within range from lb to ub is inserted at the beginning.

  • If the bit is set to 0, the value is encoded like INTEGER (lb..ub).

    1
    2
    3
    4
    bit   n          1
    +-+------------+
    |0| value - lb |
    +-+------------+
  • If the bit is set to 1, Length determinant (unconstrained) is inserted to represent the number of octets used and the value is encoded like ‘signed integer’ in other languages.

    1
    2
    3
    4
    bit         len*8 1
    +-+-----+-------+
    |1| len | value |
    +-+-----+-------+

Enumerated type

ENUMERATED {item1, item2}
The selected index is encoded like INTEGER (0..ub), where ub is equal to the number of enumeration items - 1.

1
2
3
4
bit n     1
+-------+
| index |
+-------+

ENUMERATED {item1, item2, ..., item3, item4}
A single bit indicating whether the selected enumeration index is not within the enumeration root.

  • If the bit is set to 0, the enumeration index is encoded like ENUMERATED {item1, item2}.
    1
    2
    3
    4
    bit   n     1
    +-+-------+
    |0| index |
    +-+-------+
  • If the bit is set to 1, a single bit indicating whether the selected index is larger than or equal to 64 is inserted and the value is encoded in two ways.
    • If the bit is set to 0, the value is encoded like 6-bit ‘unsigned integer’ in other languages.
      1
      2
      3
      4
      bit     6            1
      +-+-+--------------+
      |1|0| index (< 64) |
      +-+-+--------------+
    • If the bit is set to 1, Length determinant (semi-constrained with lower bound of 0) to represent the number of octets used is inserted and the value is encoded like ‘unsigned integer’ in other languages.
      1
      2
      3
      4
      bit           len*8         1
      +-+-+-----+---------------+
      |1|1| len | index (>= 64) |
      +-+-+-----+---------------+

Bit string type

BIT STRING
Length determinant (unconstrained) to represent the number of bits is inserted and the value is inserted.

1
2
3
4
bit       len   1
+-----+-------+
| len | value |
+-----+-------+

BIT STRING (SIZE(n))
The value is inserted without length determinant.

1
2
3
4
bit n     1
+-------+
| value |
+-------+

BIT STRING (SIZE(lb..ub))
Length determinant is inserted to represent the number of bits used and the value is inserted.

1
2
3
4
bit       n     1
+-----+-------+
| len | value |
+-----+-------+

Octet string type

OCTET STRING
Length determinant (unconstrained) is inserted to represent the number of octets used and the value is inserted.

1
2
3
4
bit       len*8 1
+-----+-------+
| len | value |
+-----+-------+

OCTET STRING (SIZE(n))
If n is less than 64K, the value is inserted without length determinant.

1
2
3
4
bit n*8   1
+-------+
| value |
+-------+

If n is larger than 64K, Length determinant (constrained) to represent the number of octets used is inserted and the value is inserted.

1
2
3
4
bit       len*8 1
+-----+-------+
| len | value |
+-----+-------+

OCTET STRING (SIZE(v1..v2))
Length determinant (constrained) to represent the number of octets used is inserted and the value is inserted.

1
2
3
4
bit       len*8 1
+-----+-------+
| len | value |
+-----+-------+

OCTET STRING (CONTAINING x)
Same as OCTET STRING.

Null type

It is just a placeholder. Not a single bit is used to encode NULL

Sequence type

1
2
3
4
5
SEQUENCE {
item1 Item1
item2 Item2 OPTIONAL,
item3 Item3 DEFAULT value
}

n bits are inserted where n is equal to the number of OPTIONAL and DEFAULT components. Each bit represents presence (1) and absence (0) of a component of a corresponding position. If n is larger than 64K, Length determinant (constrained) is inserted at the beginning.

1
2
3
4
5
6
7
8
9
bit n                1
+------------------+--------+-----+--------+
| bit mask (< 64K) | value1 | ... | valueN |
+------------------+--------+-----+--------+

bit n 1
+-----+-------------------+--------+-----+--------+
| len | bit mask (>= 64K) | value1 | ... | valueN |
+-----+-------------------+--------+-----+--------+
1
2
3
4
5
6
7
8
9
10
SEQUENCE {
item1 Item1,
item2 Item2 OPTIONAL,
...,
item3 Item4,
[[
item5 Item5,
item6 Item,
]]
}

A single bit indicating whether extension additions after the extension marker are present.

  • If the bit is set to 0, the rest of encoding is the same as Sequence type without extension marker and extension additions.
    1
    2
    3
    4
    bit   n        1
    +-+----------+--------+-----+--------+
    |0| bit mask | value1 | ... | valueN |
    +-+----------+--------+-----+--------+
  • If the bit is set to 1, Length determinant (normally small length) to represent the number of extension additions after the extension marker and the same number of bits are inserted. Each bit represents presence (1) and absence (0) of an extension addition of a corresponding position. Each extension addition is encoded as Open type field. An extension addition group enclosed with [[ and ]] is encoded as a Sequence type.
    1
    2
    3
    4
    bit   n        1                               len      1
    +-+----------+--------+-----+--------+-----+----------+--------+-----+--------+
    |0| bit mask | value1 | ... | valueN | len | bit mask | value1 | ... | valueN |
    +-+----------+--------+-----+--------+-----+----------+--------+-----+--------+

Sequence-of type

SEQUENCE (SIZE(v1..v2)) OF
Length determinant (constrained) to represent the number of sequence-of values included is inserted and the values are inserted.

1
2
3
+-----+--------+--------+-----+--------+
| len | value1 | value2 | ... | valueN |
+-----+--------+--------+-----+--------+

Choice type

1
2
3
4
CHOICE {
item1 Item1,
item2 Item2
}

The choice index is encoded like INTEGER (0..ub) where ub is the largest index and the actual value is inserted.

1
2
3
+-------+-------+
| index | value |
+-------+-------+
1
2
3
4
5
6
7
CHOICE {
item1 Item1,
item2 Item2,
...,
item3 Item3,
item4 Item4
}

A single bit indicating whether the selected item is within the the alternative root.

  • If the bit is set to 0, the choice index is encoded like INTEGER (0..ub) where ub is ther largest index and the actual value is inserted.
    1
    2
    3
    +-+-------+-------+
    |0| index | value |
    +-+-------+-------+
  • If the bit is set to 1, a single bit indicating whether the choice index is larger than or equal to 64 is inserted and the value is encoded in two ways.
    • If the bit is set to 0, the choice index is encoded like 6-bit ‘unsigned integer’ in other languages and the actual value is inserted.
      1
      2
      3
      4
      bit     6            1
      +-+-+---------------+-------+
      |1|0| index (< 64) | value |
      +-+-+---------------+-------+
    • If the bit is set to 1, Length determinant (semi-constrained with lower bound of 0) to represent the number of octets used is inserted and the choice index is encoded like ‘unsigned integer’ in other languages. And the actual value is inserted.
      1
      2
      3
      4
      bit           len           1
      +-+-+-----+---------------+-------+
      |1|1| len | index (>= 64) | value |
      +-+-+-----+---------------+-------+

References

  1. ITU-T X.691 ASN.1 encoding rules: Specification of Packed Encoding Rules (PER)