What's best way to do the following? Binary -> list -> binary seems unnecessary.
binary_and(A, B) ->
A2 = binary_to_list(A),
B2 = binary_to_list(B),
list_to_binary([U band V || {U, V} <- lists:zip(A2, B2)]).
If don't care of performance, your code is absolutely OK. Otherwise you can do something different.
For example Erlang supports Integers of arbitrary size:
binary_and(A, B) ->
Size = bit_size(A),
<<X:Size>> = A,
<<Y:Size>> = B,
<<(X band Y):Size>>.
Or you can handcraft your own binary zip routine:
binary_and(A,B) -> binary_and(A, B, <<>>).
binary_and(<<A:8, RestA/bytes>>, <<B:8, RestB/bytes>>, Acc) ->
binary_add(RestA, RestB, <<Acc/bytes, (A band B):8>>);
binary_and(<<>>, <<>>, Result) -> Result.
Or optimized version:
binary_and(A,B) -> binary_and(A, B, <<>>).
binary_and(<<A:64, RestA/bytes>>, <<B:64, RestB/bytes>>, Acc) ->
binary_add(RestA, RestB, <<Acc/bytes, (A band B):64>>);
binary_and(<<A:8, RestA/bytes>>, <<B:8, RestB/bytes>>, Acc) ->
binary_add(RestA, RestB, <<Acc/bytes, (A band B):8>>);
binary_and(<<>>, <<>>, Result) -> Result.
or more sophisticated
binary_and(A,B) -> binary_and({A, B}, 0, <<>>).
binary_and(Bins, Index, Acc) ->
case Bins of
{<<_:Index/bytes, A:64, _/bytes>>, <<_:Index/bytes, B:64, _/bytes>>} ->
binary_add(Bins, Index+8, <<Acc/bytes, (A band B):64>>);
{<<_:Index/bytes, A:8, _/bytes>>, <<_:Index/bytes, B:8, _/bytes>>} ->
binary_add(Bins, Index+1, <<Acc/bytes, (A band B):8>>);
{<<_:Index/bytes>>, <<_:Index/bytes>>} -> Acc
end.
Anyway you have to measure if you are really interested in performance. May be the first one is the fastest for your purposes.
If you want to see the power of the dark side...
binary_and(A, B) ->
Size = erlang:byte_size(A),
Size = erlang:byte_size(B),
Res = hipe_bifs:bytearray(Size, 0),
binary_and(Res, A, B, 0, Size).
binary_and(Res, _A, _B, Size, Size) ->
Res.
binary_and(Res, A, B, N, Size) ->
Bin = hipe_bifs:bytearray_sub(A, N) band hipe_bifs:bytearray_sub(B,N),
hipe_bifs:bytearray_update(Res, N, Bin),
binary_and(Res, A, B, N+1, Size).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With