Пример #1
0
    def __init__(self, power: int, r: int):
        self.r = r
        self.power = power

        init_matrix: list = [int_to_bit_list((2**(2**self.power)) - 1)]
        if r > 0:
            self.vectors = np.matrix([
                int_to_bit_list(x, size=self.power)
                for x in range(2**self.power)
            ]).T.tolist()
            init_matrix += self.vectors
            matrix_int_g1 = [bit_list_to_int(x) for x in init_matrix[1:]]
            self.vectors_rise = [[x] for x in range(1, self.power + 1)]

        for x in range(r - 1):
            comb: list = list(itertools.combinations(range(self.power), x + 2))

            new_matrix_g: list = []
            self.vectors_rise += comb
            for x in comb:
                val: int = matrix_int_g1[x[0]]
                for y in x:
                    val &= matrix_int_g1[y]
                new_matrix_g.append(int_to_bit_list(val, size=1 << self.power))
            init_matrix += new_matrix_g

        self.matrix_G = np.matrix(init_matrix)
        self.lengthInformation = len(self.matrix_G.tolist())
        self.lengthTotal = len(self.matrix_G.tolist()[0])
        self.lengthAdditional = self.lengthTotal - self.lengthInformation
Пример #2
0
    def __init__(self, information_length: int, polynomial: int):
        log.debug("Create cyclical _coder")

        self.lengthInformation = information_length
        self.lengthAdditional = int(math.log2(polynomial))
        self.lengthTotal = self.lengthInformation + self.lengthAdditional
        self._polynomial = plm.Polynomial(int_to_bit_list(polynomial,
                                                          rev=True))
Пример #3
0
    def _single_test(self) -> TestResult:
        """
        Method provide functionality for processing single test case
        :return: TestResult
        """
        progress: float = self._MIN_PERCENT
        step: float = self._MAX_PERCENT / self._countTest
        information: list = int_to_bit_list(self._information)
        case_result_list: List[CaseResult] = []
        global_test_statistic: SingleCoderTestThread.GlobalTestStatistic = SingleCoderTestThread.GlobalTestStatistic()
        log.debug("Test cycle begin")
        for number_of_test in range(self._countTest):
            transfer_statistic: Codec.TransferStatistic = self.channel.transfer_one_step(information)
            if transfer_statistic.result_status == EnumPackageTransferResult.SUCCESS:
                global_test_statistic.quantity_successful_package += 1
            elif transfer_statistic.result_status == EnumPackageTransferResult.REPAIR:
                global_test_statistic.quantity_repair_package += 1
            elif transfer_statistic.result_status == EnumPackageTransferResult.ERROR:
                global_test_statistic.quantity_error_package += 1
            else:
                global_test_statistic.quantity_shadow_package += 1

            global_test_statistic.quantity_correct_bits += transfer_statistic.quantity_successful_bits
            global_test_statistic.quantity_error_bits += transfer_statistic.quantity_error_bits
            global_test_statistic.based_correct_bits += transfer_statistic.based_correct_bits
            global_test_statistic.based_error_bits += transfer_statistic.based_error_bits
            progress += step
            globalSignals.stepFinished.emit(int(progress))

            case_result_list.append(CaseResult(
                successfulBits=transfer_statistic.quantity_successful_bits,
                repairBits=transfer_statistic.quantity_repair_bits,
                changedBits=transfer_statistic.quantity_changed_bits,
                errorBits=transfer_statistic.quantity_error_bits
            ))

        return TestResult(
            list_case_result=case_result_list,
            first_coder=self._currentCoder,
            second_coder=None,
            noise_type=self._noiseMode,
            noise=self.channel.noiseProbability,
            flg_cascade=True,
            successful_packages=global_test_statistic.quantity_successful_package,
            repair_packages=global_test_statistic.quantity_repair_package,
            changed_packages=global_test_statistic.quantity_repair_package,
            error_packages=global_test_statistic.quantity_error_package,
            quantity_correct_bits=global_test_statistic.quantity_correct_bits,
            quantity_error_bits=global_test_statistic.quantity_error_bits,
            based_correct_bits=global_test_statistic.based_correct_bits,
            based_error_bits=global_test_statistic.based_error_bits
        )
Пример #4
0
    def encoding(self, information: list):
        log.info("Fountain LT-_coder start coding of package {0}".format(
            information))
        combination_blocks: list = []
        information = [0] * abs(len(information) - self.lengthInformation
                                ) + information  # добавление 0 битов вначало
        for x in range(0, len(information), self._sizeBlock):
            combination_blocks.append(
                bit_list_to_int(
                    information[x:min(x + self._sizeBlock, len(information))]))

        answer: list = []

        for x in range(self._countCodingBlocks):
            value: int = 0
            count: int = 0
            for y in int_to_bit_list(self._generationBlocks[x],
                                     self._countBlocks):
                if y == 1:
                    value ^= combination_blocks[count]
                count += 1
            answer.append(int_to_bit_list(value, self._sizeBlock))

        return [y for x in answer for y in x]
Пример #5
0
    def _get_graph(self) -> List[List[Tuple[int, List[int]]]]:
        """
        Формирует список представляющий граф переходов, где каждая вершина
        [
            [номер вершины в которую переходим, [биты которые соответвуют переходу]],
            ...
        ]
        """
        answer: list = []
        for x in range(2**self._countRegisters):
            vertex: list = []
            self._register = x
            list_integers: list = int_to_bit_list(x, self._countRegisters)
            list_integers = cycle_shift_list(list_integers)
            list_integers[0] = 0
            vertex.append([bit_list_to_int(list_integers), self._do_step(0)])
            self._register = x
            list_integers[0] = 1
            vertex.append([bit_list_to_int(list_integers), self._do_step(1)])
            answer.append(vertex)

        self._register = 0
        return answer
Пример #6
0
    def _do_step(self, information_bit: int) -> list:
        """
        Method contain functionality for generation _graph of
        :param information_bit:
        :return:
        """
        log.debug("Step coding convolution - {0}".format(information_bit))
        self._register <<= 1

        # зануление старшего бита
        self._register &= (1 << (self._countRegisters + 1)) - 1
        self._register += information_bit

        answer = []
        power = 0
        for count in range(self._countPolynomials):
            added_bit = 0
            for x in int_to_bit_list(self._listPolynomials[count]
                                     & self._register):
                added_bit ^= x
            answer.append(added_bit % 2)
            power += 1
        return answer
Пример #7
0
    def decoding(self, information: list):
        def vec_xor(a, b):
            return [a[i] ^ b[i] for i in range(len(a))]

        def vec_mul(a, b):
            return [a[i] & b[i] for i in range(len(a))]

        def vec_inv(a):
            return [x ^ 1 for x in a]

        def vec_gen(a, b):
            return [a for x in range(b)]

        result_voice: list = []
        for vector in self.matrix_G.tolist()[::-1][:-1]:
            voice: int = 1  # голосовалка

            # проверка на ортогональность
            orthogonal_vectors: list = [vector]
            for test_vector in self.matrix_G.tolist()[1:]:
                for x in orthogonal_vectors:
                    if sum(vec_mul(
                            x, test_vector)) % 2 != 0 or test_vector == vector:
                        break
                else:
                    orthogonal_vectors.append(test_vector)

            orthogonal_vectors = orthogonal_vectors[1:]
            # проверка на ортогональность

            for options_mul in range(1 << len(orthogonal_vectors)):
                orthogonal_vec_num: int = 0

                val_vector_mul = vec_gen(
                    1, len(information)
                )  # заглушка состоящая из одних единиц, нужна для умножения
                for option in int_to_bit_list(options_mul,
                                              size=len(orthogonal_vectors)):
                    if option:
                        val_vector_mul = vec_mul(
                            val_vector_mul,
                            orthogonal_vectors[orthogonal_vec_num])
                    else:
                        val_vector_mul = vec_mul(
                            val_vector_mul,
                            vec_inv(orthogonal_vectors[orthogonal_vec_num]))
                    orthogonal_vec_num += 1

                voice += 1 if sum(vec_mul(val_vector_mul,
                                          information)) % 2 != 0 else -1

            result_voice.append(0 if voice < 1 else 1)

        first_sum: int = information.copy()
        counter: int = 0
        for vector in self.matrix_G.tolist()[::-1][:-1]:
            first_sum = vec_xor(
                vec_mul(vector, vec_gen(result_voice[counter],
                                        len(information))), first_sum)
            counter += 1

        result_voice.append(0 if sum(first_sum) > 5 else 1)
        temp_matrix: list = self.matrix_G.tolist()
        result_voice.reverse()
        decoding_information: list = vec_gen(0, len(information))
        for x in range(len(temp_matrix)):
            decoding_information = vec_xor(
                vec_mul(temp_matrix[x],
                        vec_gen(result_voice[x], len(information))),
                decoding_information)

        decoding_information.reverse()  # исправленное кодовое слово
        result_voice[0] = 0 if sum(decoding_information) < 5 else 1

        return result_voice
Пример #8
0
    def decoding(self, information: list):
        """
        Декодер LT-фонтанного кода с заранее установленным генератором случайных чисел
        :param information: list Закодированная информация, представленная в виде массива битов
        :return: list Декодированная информация, представленная в виде массива битов
        """
        log.info(
            "Fountain LT-decoder decoding of package {0}".format(information))
        decoded_set_list: list = [
            set(bit_list_to_int_list(int_to_bit_list(x, self._sizeBlock)))
            for x in self._generationBlocks
        ]
        decoded_set_list.append(set())  # костыль, чтобы работало
        is_kill: bool = False

        # Divided into blocks
        status: list = [False for x in range(self._countBlocks)]
        status.append(True)  # One block should be always true

        block_int_values: List[int] = []
        for num_of_block in range(0, len(information), self._sizeBlock):
            help_data: list = []
            for num_of_bit in range(self._sizeBlock):
                if (num_of_block + num_of_bit) < len(information):
                    help_data.append(information[num_of_block + num_of_bit])
            block_int_values.append(bit_list_to_int(help_data))
        block_int_values.append(0)  # One block should be always 0

        answer: list = [0] * self._countCodingBlocks
        while not is_kill and {True} != set(status):
            is_kill = True
            for iterator_f in range(len(decoded_set_list)):
                for iterator_s in range(len(decoded_set_list)):
                    difference = decoded_set_list[
                        iterator_f] - decoded_set_list[iterator_s]
                    if len(difference) == 1 and (
                            decoded_set_list[iterator_s] -
                            decoded_set_list[iterator_f]) == set():
                        is_kill = False
                        status[list(difference)[0]] = True
                        answer[list(difference)[0]] = block_int_values[
                            iterator_f] ^ block_int_values[iterator_s]
                        for z in range(len(decoded_set_list)):
                            if list(difference)[0] in decoded_set_list[z]:
                                block_int_values[z] ^= answer[list(difference)
                                                              [0]]
                                decoded_set_list[
                                    z] = decoded_set_list[z] - difference

        if set(status) != {True}:
            log.debug(
                "Lacks of blocks for decoding package with fountain _coder")
            raise CodingException(
                message=CodingException.LACKS_OF_BLOCKS_FOR_DECODING.message,
                long_message=CodingException.LACKS_OF_BLOCKS_FOR_DECODING.
                long_message)

        # Form result in digital format
        answer = answer[:ceil(self.lengthInformation / self._sizeBlock)]
        answer.reverse()
        answer = [int_to_bit_list(x, self._sizeBlock)
                  for x in answer[:-1]] + [int_to_bit_list(answer[-1])]
        # Unpacking answer
        answer = [y for x in answer for y in x]
        answer = answer[:self.lengthInformation]

        if len(answer) < self.lengthInformation:
            answer += [0] * (self.lengthInformation - len(answer))

        return answer