public static String dump(byte[] data, int desiredCharWidth, int... highlights) {
        if (data == null || data.length < 1) {
            return "";
        }
        Set<Integer> highlightsSet = Arrays.stream(highlights).boxed().collect(Collectors.toSet());
        // We copy the array to avoid mutations
        data = Arrays.copyOf(data, data.length);
        StringBuilder hexString = new StringBuilder();
        Pair<Integer, Integer> rowIndexCalculation = calculateBytesPerRowAndIndexWidth(data.length, desiredCharWidth);
        int maxBytesPerRow = rowIndexCalculation.getLeft();
        int indexWidth = rowIndexCalculation.getRight();
        for (int byteIndex = 0, rowIndex = 0; byteIndex < data.length; byteIndex = byteIndex + maxBytesPerRow, rowIndex = rowIndex + 1) {
            String indexString = String.format("%1$" + indexWidth + "s|", byteIndex).replace(' ', '0');
            hexString.append(indexString);
            for (int columnIndex = 0; columnIndex < maxBytesPerRow; columnIndex++) {
                int absoluteIndex = byteIndex + columnIndex;
                if (absoluteIndex < data.length) {
                    if(highlightsSet.contains(absoluteIndex)) {
                        hexString.append("\033[0;31m");
                    }
                    hexString.append(String.format("%02x ", data[absoluteIndex]));
                    if(highlightsSet.contains(absoluteIndex)) {
                        hexString.append("\033[0m");
                    }
                } else {
                    // align with empty byte representation
                    hexString.append(StringUtils.repeat(" ", byteWidth));
                }
            }
            int endIndex = byteIndex + maxBytesPerRow;
            if (endIndex >= data.length) {
                endIndex = data.length;
            }
            String stringRepresentation = maskString(ArrayUtils.subarray(data, byteIndex, endIndex));
            if (stringRepresentation.length() < maxBytesPerRow) {
                stringRepresentation += StringUtils.repeat(" ", (maxBytesPerRow - stringRepresentation.length()) % maxBytesPerRow);
            }
            hexString.append(String.format("'%s'\n", stringRepresentation));
        }
        // remove last newline
        return hexString.substring(0, hexString.length() - 1);
    }
dumps a 56 char wide hex string

@param data bytes to dump
@return the hex string
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/utils/hex/Hex.java