# 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

4bit 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

4bit 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 | bit 7 1 |

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 | bit 14 1 |

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

## Boolean type

`BOOLEAN`

A single bit is set to 1 for `TRUE`

and 0 for `FALSE`

1 | bit 1 |

## 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 | bit n 1 |

`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

4bit 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

4bit 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 | bit n 1 |

`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

4bit 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

4bit 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

4bit len*8 1

+-+-+-----+---------------+

|1|1| len | index (>= 64) |

+-+-+-----+---------------+

- If the bit is set to 0, the value is encoded like 6-bit ‘unsigned integer’ in other languages.

## Bit string type

`BIT STRING`

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

1 | bit len 1 |

`BIT STRING (SIZE(n))`

The value is inserted without length determinant.

1 | bit n 1 |

`BIT STRING (SIZE(lb..ub))`

*Length determinant* is inserted to represent the number of bits used and the value is inserted.

1 | bit n 1 |

## Octet string type

`OCTET STRING`

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

1 | bit len*8 1 |

`OCTET STRING (SIZE(n))`

If *n* is less than 64K, the value is inserted without length determinant.

1 | bit n*8 1 |

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

1 | bit len*8 1 |

`OCTET STRING (SIZE(v1..v2))`

*Length determinant (constrained)* to represent the number of octets used is inserted and the value is inserted.

1 | bit len*8 1 |

`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 | SEQUENCE { |

*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 | bit n 1 |

1 | SEQUENCE { |

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

4bit 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

4bit 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 | +-----+--------+--------+-----+--------+ |

## Choice type

1 | CHOICE { |

The choice index is encoded like `INTEGER (0..ub)`

where *ub* is the largest index and the actual value is inserted.

1 | +-------+-------+ |

1 | CHOICE { |

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

4bit 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

4bit len 1

+-+-+-----+---------------+-------+

|1|1| len | index (>= 64) | value |

+-+-+-----+---------------+-------+

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

# References

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