asn.1ber

Encoding of first identifier of an OID in ASN.1 into BER


OID's it seems are a way to represent a tree like structure.

Eg 1.3.6.1 being iso(1).org(3).did(6).internet(1)

The encoding scheme used most commonly seems to be BER and I am confused about the encoding of the first two digits. Why are the first two digits encoded into a single byte and why is it like this:

int first_digit = first_byte / 40;
int second_byte = first_byte % 40;

Is it assumed that the first two bytes are always small numbers and hence can be 'stored' easily in one byte? If so I can understand that.

But why the use of the magic number 40? Why 40?

eg. the first byte in above 1.3.xxx case would be encoded as 43.


Solution

  • Quoting from "ASN.1 Complete" book, by prof. John Larmouth, section 3.14 (the book is available for free from http://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf):

    The octets encoding the first two arcs were (in 1986) thought to be unlikely to ever have large values, and that using two octets for these two arcs was "a bad thing". So an "optimization" (mandatory) was introduced.

    Well, there are three top-level arcs, and we can accommodate encodings for up to 128 arcs (0 to 127) in a single octet with the "more bit" concept described above. 128 divided by 3 is about 40! Let's assume the first two top-level arcs will never have more than 40 sub-arcs, and allocate the first 40 pseudo-arcs to top-level arc 0, the next 40 to top-level arc 1, and the remainder to top-level arc 2.