No, there is not such formating option but you can do something like:
io:format("<<~s>>~n", [[io_lib:format("~2.16.0B",[X]) || <<X:8>> <= <<255,16>> ]]).
There is a lot faster solution if you need.
-module(bin_to_hex).
-compile([native, {hipe, [o3]}]).
-export([bin_to_hex/1]).
bin_to_hex(B) when is_binary(B) ->
bin_to_hex(B, <<>>).
-define(H(X), (hex(X)):16).
bin_to_hex(<<>>, Acc) -> Acc;
bin_to_hex(Bin, Acc) when byte_size(Bin) band 7 =:= 0 ->
bin_to_hex_(Bin, Acc);
bin_to_hex(<<X:8, Rest/binary>>, Acc) ->
bin_to_hex(Rest, <<Acc/binary, ?H(X)>>).
bin_to_hex_(<<>>, Acc) -> Acc;
bin_to_hex_(<<A:8, B:8, C:8, D:8, E:8, F:8, G:8, H:8, Rest/binary>>, Acc) ->
bin_to_hex_(
Rest,
<<Acc/binary,
?H(A), ?H(B), ?H(C), ?H(D), ?H(E), ?H(F), ?H(G), ?H(H)>>).
-compile({inline, [hex/1]}).
hex(X) ->
element(
X+1, {16#3030, 16#3031, 16#3032, 16#3033, 16#3034, 16#3035, 16#3036,
16#3037, 16#3038, 16#3039, 16#3041, 16#3042, 16#3043, 16#3044,
16#3045, 16#3046, 16#3130, 16#3131, 16#3132, 16#3133, 16#3134,
16#3135, 16#3136, 16#3137, 16#3138, 16#3139, 16#3141, 16#3142,
16#3143, 16#3144, 16#3145, 16#3146, 16#3230, 16#3231, 16#3232,
16#3233, 16#3234, 16#3235, 16#3236, 16#3237, 16#3238, 16#3239,
16#3241, 16#3242, 16#3243, 16#3244, 16#3245, 16#3246, 16#3330,
16#3331, 16#3332, 16#3333, 16#3334, 16#3335, 16#3336, 16#3337,
16#3338, 16#3339, 16#3341, 16#3342, 16#3343, 16#3344, 16#3345,
16#3346, 16#3430, 16#3431, 16#3432, 16#3433, 16#3434, 16#3435,
16#3436, 16#3437, 16#3438, 16#3439, 16#3441, 16#3442, 16#3443,
16#3444, 16#3445, 16#3446, 16#3530, 16#3531, 16#3532, 16#3533,
16#3534, 16#3535, 16#3536, 16#3537, 16#3538, 16#3539, 16#3541,
16#3542, 16#3543, 16#3544, 16#3545, 16#3546, 16#3630, 16#3631,
16#3632, 16#3633, 16#3634, 16#3635, 16#3636, 16#3637, 16#3638,
16#3639, 16#3641, 16#3642, 16#3643, 16#3644, 16#3645, 16#3646,
16#3730, 16#3731, 16#3732, 16#3733, 16#3734, 16#3735, 16#3736,
16#3737, 16#3738, 16#3739, 16#3741, 16#3742, 16#3743, 16#3744,
16#3745, 16#3746, 16#3830, 16#3831, 16#3832, 16#3833, 16#3834,
16#3835, 16#3836, 16#3837, 16#3838, 16#3839, 16#3841, 16#3842,
16#3843, 16#3844, 16#3845, 16#3846, 16#3930, 16#3931, 16#3932,
16#3933, 16#3934, 16#3935, 16#3936, 16#3937, 16#3938, 16#3939,
16#3941, 16#3942, 16#3943, 16#3944, 16#3945, 16#3946, 16#4130,
16#4131, 16#4132, 16#4133, 16#4134, 16#4135, 16#4136, 16#4137,
16#4138, 16#4139, 16#4141, 16#4142, 16#4143, 16#4144, 16#4145,
16#4146, 16#4230, 16#4231, 16#4232, 16#4233, 16#4234, 16#4235,
16#4236, 16#4237, 16#4238, 16#4239, 16#4241, 16#4242, 16#4243,
16#4244, 16#4245, 16#4246, 16#4330, 16#4331, 16#4332, 16#4333,
16#4334, 16#4335, 16#4336, 16#4337, 16#4338, 16#4339, 16#4341,
16#4342, 16#4343, 16#4344, 16#4345, 16#4346, 16#4430, 16#4431,
16#4432, 16#4433, 16#4434, 16#4435, 16#4436, 16#4437, 16#4438,
16#4439, 16#4441, 16#4442, 16#4443, 16#4444, 16#4445, 16#4446,
16#4530, 16#4531, 16#4532, 16#4533, 16#4534, 16#4535, 16#4536,
16#4537, 16#4538, 16#4539, 16#4541, 16#4542, 16#4543, 16#4544,
16#4545, 16#4546, 16#4630, 16#4631, 16#4632, 16#4633, 16#4634,
16#4635, 16#4636, 16#4637, 16#4638, 16#4639, 16#4641, 16#4642,
16#4643, 16#4644, 16#4645, 16#4646}).
Which performs 90MB/s on mine notebook i5 CPU M 520 @ 2.40GHz when tested on 10MB chunks. But optimization was brought to the extreme there. It can also do 97MB if using 16bit lookup but it is crazy and too long to post here.
You could do:
[ hd(erlang:integer_to_list(Nibble, 16)) || << Nibble:4 >> <= Binary ].
Which would return you a list(string) containing the hex digits of the binary. While I doubt the efficiency of this operation is going to have any effect on the runtime of your system, you could also have this bin_to_hex
function return an iolist which is simpler to construct and will be flattened when output anyway. The following function returns an iolist with the formatting example you gave:
bin_to_hex(Bin) when is_binary(Bin) ->
JoinableLength = byte_size(Bin) - 1,
<< Bytes:JoinableLength/binary, LastNibble1:4, LastNibble2:4 >> = Bin,
[ "<< ",
[ [ erlang:integer_to_list(Nibble1, 16), erlang:integer_to_list(Nibble2, 16), ", " ]
|| << Nibble1:4, Nibble2:4 >> <= Bytes ],
erlang:integer_to_list(LastNibble1, 16),
erlang:integer_to_list(LastNibble2, 16),
" >>" ].
It's a bit ugly, but runs through the binary once and doesn't traverse the output list (otherwise I'd have used string:join to get the interspersed ", " sequences). If this function is not the inner loop of some process (I have a hard time believing this function will be your bottleneck), then you should probably go with some trivially less efficient, but far more obvious code like:
bin_to_hex(Bin) when is_binary(Bin) ->
"<< " ++ string:join([byte_to_hex(B) || << B >> <= Bin ],", ") ++ " >>".
byte_to_hex(<< N1:4, N2:4 >>) ->
[erlang:integer_to_list(N1, 16), erlang:integer_to_list(N2, 16)].