Cheatography

Erlang Binaries Cheat Sheet by Fylke

Summarizing the syntax for handling binary data in Erlang.

Overview

 Erlang can match binaries just as any list of things. ``<> = Bin`` divides the binary ``Bin`` into three elements of type ``integer`` of one byte each. This means that ``Bin`` has to be 24 bits long, or we get a ``badmatch``. You can also make partial matches, in a ``[Head | Tail]`` fashion, by putting ``/bitstring`` on the last element, like so: ``<> = Bin``. This is a type modifier and tells Erlang that there are two 8-bit elements, in ``E1`` and ``E2`` respec­tively, and then an undete­rmined amount of bits stored in ``E3``.

Type Modifiers

 Type Size in bits Remarks ``integer`` As many as it takes Default size is 8 bits ``float`` 64|32|16 Need to specify length if other than default: ``<>`` ``binary|bytes`` 8 per chunk Anything matched must be of size evenly divisible by 8 (this is default) ``bitstring|bits`` 1 per chunk Will always match, use as Tail for a list ``utf8|utf16|utf32`` 8-32, 16-32, and 32 ``<<"a­bc"/­utf­8>>`` is the same as ``<<\$­a/utf8, \$b/utf8, \$c/utf­8>>`` ``signed|unsigned`` N/A Default is unsigned ``big|little|native`` N/A Endianness - ``native`` is resolved at load time to whatever the CPU uses ``unit:IntLiteral`` N/A Define a custom unit of length 1..256

Examples

 Expression Result ``<<97, 98, 99>>`` ``<<"a­bc">>`` (turn off with ``shell:­str­ing­s(f­alse)``) ``<> = <<7, 42>>`` ``A = 114`` ``B = 10`` ``<> = <<1, 17>>`` ``1.6272­068­023­681­64e-5`` ``<> = <<2­55>>`` ``-1`` ``<> = <<255, 0>>`` ``65280`` ``<> = <<255, 0>>`` ``255`` ``<<"p­öpc­örn­"­/ut­f8>>`` How Erlang handles unicode
When constr­ucting a binary, if the size of an integer
``N``
is too large to fit inside the given segment, the most signif­icant bits are silently discarded and only the
``N``
least signif­icant bits kept.

Segments

 Each segment in a binary has the following general syntax: ``Value:Size/TypeSpecifierList``. The ``Size`` and ``TypeSpecifier`` can be omitted. ``Value`` is either a literal or a variable, ``Size`` is multiplied by the unit in ``TypeSpecifierList``, and can be any expression that evaluates to an ``integer``1. Think of 'Size' as the number of items of the type in the 'TypeSpecifierList' Contrived example: ``<>`` has a total size of 4*8 = 32 bits, and it contains a signed integer in little endian byte order.
1 Mostly true, see Bit Syntax Expres­sions in Erlang docume­ntation for complete picture.

Binary Compre­hension Example

 Just like with lists, there is a notation for binary compre­hen­sion. Below is an example of how to use this to convert a 32 bit integer into a hex repres­ent­ation: ``int_as­_he­x(Int) ->`` `` ­ ­ ­ ­Int­AsBin = <­>,`` `` ­ ­ ­ ­"­0x" ++ lists:­fla­tte­n([­byt­e_t­o_h­ex(­<>) || <> <= IntAsB­in]).`` ``byte_t­o_h­ex(­<>) ->`` `` ­ ­ ­ ­[in­teg­er_­to_­lis­t(N­ibble1, 16), intege­r_t­o_l­ist­(Ni­bble2, 16))].``
You can mix list- and binary compre­hen­sion: if the generator is a list, use
``<-``
, if it's a binary, use
``<=``
. If you want the result to be a binary, use
``<<>>``
, if you want a list, use
``[]``
around the expres­sion.

Troubl­esh­ooting

 Use the Erlang shell to trial and error you way to a correct expres­sion. A useful tool for unders­tanding why your binaries are badmat­ching is ``bit_size``: ``bit_si­ze(­<<1­/in­teg­er>­>). => 8`` ``bit_si­ze(­<<<­<1:1, 0:1>>/­bit­str­ing­>>). => 2`` ``bit_si­ze(­<<1.0/­flo­at>­>). => 64`` ``bit_si­ze(­<<<­<1, 2>>­/bi­nar­y>>). => 16`` A related one is ``byte_size``: ``MinByt­esT­oEn­cod­eNumber = byte_s­ize­(bi­nar­y:e­nco­de_­uns­ign­ed(­Num­ber)).``