I don’t know why but Erlang bit syntax always confused me. I always skipped it while reading the docs, until, well, now that I need it. I should say this is not meant to be an exhaustive how-to by any means. It’s just a collection of notes, but howto sounded better. 🙂 There are better guides out there. [Reference docs too.]
Anyway. Here’s some binary data in Erlang:
<<16#1192c05a:32>>
What does all this mean? Let’s analyze it, left to right.
16#
This specifies we want to express the number in base 16.
- We have an eight digits hex number.
- No type specification is provided: default is unsigned integer.
- No unit specification is provided: default for integer is 1, which means ‘bits’.
:32
Size specification: this tells erlang to consider 32 units, which in our case means 32 bits, since we are dealing with bits.
Let’s evaluate it:
86> <<16#2092105a:32>>.
<<32,146,16,90>>
What if we forget to specify the size spec? In that case the default will apply and since we’re dealing with an integer type, the default is 8 (bits). For Erlang this means we are going to return the least significant byte:
87> <<16#2092105a>>.
<<90>>
Now that we know that, we can get a subset of bits by setting the size accordingly:
88> <<16#2092105a:16>>.
<<16,90>> %two least significant bytes
We don’t need to specify a size multiple of 8:
89> <<16#1192FFFF:15>>.
<<255,127:7>>
It’s pretty cool how easy it is to slice bytes apart at the bit level. I was sort of surprised that if we slice some internal bits it looks like the bits at the right are moved to the left. E.g. here we take the 4 least significant bits of the first 0xFF:
90> <<16#FF:4,0,16#FF,0>>.
but instead of obtaining:
<<16:4,0,255,0>>
F 00 FF 00
we get:
<<240,15,240,0:4>>
F0 0F F0 0 [240 == F0]
Also, the value doesn’t need to be a literal, it can be an expression:
91> N = 16#FF00FF01.
4278255361
92> <<N:32>>.
<<255,0,255,1>>
And therefore, given some binary data, we can also pattern-match it super easily:
<SourcePort:16, DestinationPort:16, CheckSum:16, Payload/binary>> = SomeBinary.
There’s more to Erlang bit syntax than this, but I’ll stop here for now.