% Copyright (c) 2025 Onomondo ApS & sysmocom - s.f.m.c. GmbH. All rights reserved. % % SPDX-License-Identifier: AGPL-3.0-only % % Author: Philipp Maier / sysmocom - s.f.m.c. GmbH -module(utils). -export([binary_to_hex/1, hex_to_binary/1, join_binary_list/1, integer_to_bytes/1, lpad_binary/3]). % Converts a single hex digit (e.g. <<"A">>) into its integer representation. hexstr_digit_to_int(HexDigit) -> [HexDigitInt] = HexDigit, HexDigitIntCap = HexDigitInt bor 32, case HexDigitIntCap of 48 -> 0; 49 -> 1; 50 -> 2; 51 -> 3; 52 -> 4; 53 -> 5; 54 -> 6; 55 -> 7; 56 -> 8; 57 -> 9; 97 -> 10; 98 -> 11; 99 -> 12; 100 -> 13; 101 -> 14; 102 -> 15 end. % Converts a single hex octet (e.g. <<"1A">>) into its integer representation. hexstr_octet_to_int(HexOctet) -> HexDigits = [[X] || <> <= HexOctet], HexDigitsInt = [hexstr_digit_to_int(X) || X <- HexDigits], [HexOctetIntH | T] = HexDigitsInt, [HexOctetIntL | _] = T, HexOctetIntH * 16 + HexOctetIntL. % Converts a binary into a printable hex-string (also a binary). binary_to_hex(Binary) -> EncList = [io_lib:format("~2.16.0B", [X]) || <> <= Binary], list_to_binary(string:join(io_lib:format("~s", [EncList]), "")). % Converts a printable hex-string (int the form of a binary) to a binary. hex_to_binary(HexStr) -> OctetsStr = [<> || <> <= HexStr], list_to_binary([hexstr_octet_to_int(X) || X <- OctetsStr]). % Joins (concatenates) a list of binaries into a single large binary join_binary_list([]) -> % An empty list will result into an empty binary <<>>; join_binary_list([Single]) -> % A list that contains only of a single binary will result into that single binry. Single; join_binary_list([H | T]) -> % Lists with multiple binaries get joined into a single large binary lists:foldl(fun(Binary, Joined) -> <> end, H, T); join_binary_list(Binary) -> % In case someone uses this function on a binary directly, we transparently return that binary. Binary. % Convert an integer into a binary that contains the integer as a series of bytes (network byte order) integer_to_bytes(Integer) -> % Convert the integer to a list with hex digits (nibbles) IntegerDigits = integer_to_list(Integer, 16), % Make sure that the list contains an even number of digits (nibbles) IntegerDigitsPadded = case length(IntegerDigits) rem 2 of 1 -> ["0" | IntegerDigits]; _ -> IntegerDigits end, % Merge the list of hex digits into a single hex string (binary) and convert that binary into a binary IntegerAsHexstring = list_to_binary(IntegerDigitsPadded), hex_to_binary(IntegerAsHexstring). % Padd a binary from the left with a specified padding byte lpad_binary(Binary, Padding, Length) -> if byte_size(Binary) >= Length -> Binary; true -> BinaryPadded = <>, lpad_binary(BinaryPadded, Padding, Length) end.