Erlang io:formatting a binary to hex

后端 未结 7 676
难免孤独
难免孤独 2020-12-29 06:06

Can I format an Erlang binary so that each byte is written in hex? I.e.,

> io:format(???, [<<255, 16>>]).
<>
7条回答
  •  旧时难觅i
    2020-12-29 06:20

    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)].
    

提交回复
热议问题