Erlang Central

Difference between revisions of "Decoding Binary Messages"

From ErlangCentral Wiki

(missed a bit)
(Solution)
(2 intermediate revisions by 2 users not shown)
Line 5:Line 5:
 
== Solution ==
 
== Solution ==
  
This would probably be an appropriate place to demonstrate some of Erlang's built-in support for communicating with remote systems, converting text into binary format, and so forth. But, we will save those topics for their own recipes. This topic will be treated as was done in the original Schematics Cookbook.  
+
This would probably be an appropriate place to demonstrate some of Erlang's built-in support for communicating with remote systems, converting text into binary format, and so forth. But, we will save those topics for their own recipes. This topic will be treated as was done in the original [http://schemecookbook.org/ Schematics Cookbook].  
  
 
<code>
 
<code>

Revision as of 06:15, 9 March 2007

Problem

You have a string containing the characters 0 and 1, representing, in binary, the ASCII values of some text. You want to convert this string into normal, readable, ASCII.

Solution

This would probably be an appropriate place to demonstrate some of Erlang's built-in support for communicating with remote systems, converting text into binary format, and so forth. But, we will save those topics for their own recipes. This topic will be treated as was done in the original Schematics Cookbook.

decode_message(L) -> decode_message(L,[]).
decode_message([],Acc) -> lists:reverse(Acc);
decode_message(L,Acc) ->
    {BinC,T} = lists:split(8,L),
    {ok,[C],[]} = io_lib:fread("~2u",BinC),
    decode_message(T,[C|Acc]).

%% The following message appeared on a ThinkGeek tshirt
%% on the first of april 2004.
1> decode_message(
1>     "010010010010000001110011011010000110111"
1>     "101110000011100000110010101100100001000" 
1>     "000110000101110100001000000101010001101" 
1>     "000011010010110111001101011010001110110" 
1>     "010101100101011010110010000001101111011"
1>     "011100010000001000001011100000111001001" 
1>     "101001011011000010000001000110011011110" 
1>     "110111101101100011100110010000001000100" 
1>     "011000010111100100101100001000000110000" 
1>     "101101110011001000010000001100001011011" 
1>     "000110110000100000010010010010000001100" 
1>     "111011011110111010000100000011101110110" 
1>     "000101110011001000000111010001101000011" 
1>     "010010111001100100000011011000110111101" 
1>     "110101011100110111100100100000011100110" 
1>     "110100001101001011100100111010000100001").
"I shopped at ThinkGeek on April Fools Day, and all I got was this lousy shirt!

The Erlang system comes with io_lib functions to convert from strings to numbers (via io_lib:fread) and vice-versa (via io_lib:format). For example:

2> io_lib:fread("~d", "100").
{ok,"d",[]}
% Note:  The "d" is just an aspect of Erlang's odd handling of
% strings as lists of decimal numbers.  The ASCII value of the
% character "d" is 100:
3> $d.
100
4> io_lib:format("~B", [100]).
["100"]

Both procedures take an additional argument which specifies the radix ("base") to use. The default is 10, but values of 2 through 36 may also be used. In the recipe above the radix 2 (format of "~2u") specifies that we are converting to numbers from a base 2 representation. If, for example, the numbers were represented in base 16 (hexadecimal) it would be a simple matter to use "~16u" instead.