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