def decode(self, bit_arr: ba.bitarray) -> ba.bitarray: """ :param bit_arr: bitarray that length multiple of self.n :param is_reshaped: flag is it array shape - into ndarray (l,self.k), where l - some value greater 0 :return: decoded array multiple of self.k """ # msg is being partited on pieces # print(bit_arr, len(bit_arr)) bit_list = BaseCode.reshape_to_np_arr(bit_arr, self.n) decoded_arr = ba.bitarray() for i in range(len(bit_list)): w_edit = RM_Code.get_w_edit(bit_list[i]) # w^~= w_edit = w_i for j in range(self.m): H_i_m = RM_Code.get_H_i_m(j + 1, self.m) w_edit = np.matmul(w_edit, H_i_m) max_index_j = np.argmax(np.abs(w_edit)) vj: ba.bitarray = self.get_v_j(max_index_j) first_bit: tuple = (int(w_edit[max_index_j] > 0), ) decoded_arr.extend(first_bit) decoded_arr.extend(vj) return decoded_arr
def decode(self, bit_arr: ba.bitarray): bit_list = BaseCode.reshape_to_np_arr(bit_arr, self.n) decoded_arr = ba.bitarray() for kij in range(len(bit_list)): i = self.r J = self.J w = bit_list[kij].copy() decoded = np.zeros(self.k, dtype=np.int8) v_i = np.zeros(self.n, dtype=np.int8) for j in range(len(J) - 1, -1, -1): J_j = J[j] if len(J_j) != i: i -= 1 w = np.logical_xor(w, v_i) v_i = np.zeros(self.n, dtype=np.int8) count = 0 verifications = self.get_verification_vectors(J_j) for v in verifications: count += RM_Code.scalar(w, v) size_half = len(verifications) // 2 if count > size_half: decoded[j] = 1 v_i = np.logical_xor(v_i, self.get_row_by_j(J_j)) elif count == size_half: print(f"Error. The word {w} can be fixed.") decoded_arr.extend(decoded) return decoded_arr
def get_bit_view_nums(self): ans = [] for i in range(self.n): str_bits = BaseCode.int_to_str_bits(i, self.m) bit_a = ba.bitarray(str_bits) bit_a.reverse() ans.append(bit_a) return ans
def encode(self, bit_arr: ba.bitarray, is_reshaped=False) -> ba.bitarray: """ :param bit_arr: bitarray that length multiple of self.k :param is_reshaped: flag is it array shape - into ndarray (l,self.k), where l - some value greater 0 :return: encoded array multiple of self.n """ # msg is being partited on pieces bit_list = BaseCode.reshape_to_np_arr(bit_arr, self.k, is_reshaped) coded_arr = ba.bitarray() # encode log_xor = np.matmul(bit_list, self.g) % 2 coded_arr.extend(log_xor.ravel()) return coded_arr
def get_verification_vectors(self, J): J_c = self.get_complementary_set(J) shifts = self.get_permissible_bit_shift(J) shifts = [BaseCode.get_num_from_bit(shift[::-1]) for shift in shifts] row = self.get_row_by_j(J_c) ans = np.ndarray((len(shifts), self.n), dtype=np.int8) for i, shift in enumerate(shifts): shifted_row = row.copy() if shift != 0: shifted_row[shift:] = shifted_row[:-shift] shifted_row[:shift] = np.zeros(shift, dtype=np.int8) ans[i][:] = shifted_row return ans
def decode(self, bit_arr: ba.bitarray) -> ba.bitarray: """ :param bit_arr: bitarray that length multiple of self.n :param is_reshaped: flag is it array shape - into ndarray (l,self.k), where l - some value greater 0 :return: decoded array multiple of self.k """ # msg is being partited on pieces print(bit_arr, len(bit_arr)) bit_list = BaseCode.reshape_to_np_arr(bit_arr, self.n) decoded_arr = ba.bitarray() for i in range(len(bit_list)): # Algo from lecture # find syndrome s = wH s = np.matmul(bit_list[i], self.H) % 2 u = None if GolayCode.wt(s, is_np_array=True) <= 3: u = np.concatenate((s, np.zeros(self.n_k, dtype=np.int8))) else: for j in range(len(self.B)): log_xor = np.logical_xor(s, self.B[j]) if GolayCode.wt(log_xor, is_np_array=True) <= 2: u = np.concatenate((log_xor, np.eye(self.n_k)[j])) break # find syndrome b = sB sB = np.matmul(s, self.B) % 2 if self.wt(sB) <= 3: u = np.concatenate((np.zeros(self.n_k, dtype=np.int8), sB)) else: for j in range(len(self.B)): log_xor = np.logical_xor(sB, self.B[j]) if GolayCode.wt(log_xor, is_np_array=True) <= 2: u = np.concatenate((np.eye(self.n_k)[j], log_xor)) break if u is None: invalid_sequence = bit_arr[self.n * i:self.n * (i + 1)] err_str = f"""Can not decode the message {GolayCode.ba_to_str_bits(invalid_sequence)}. Please repit the transfer of data.""" raise ValueError(err_str) else: on_flush = np.logical_xor(bit_list[i], u)[0:self.k] decoded_arr.extend(on_flush) return decoded_arr
def decode_file(self, file_in, file_out, make_table, is_fix_err: bool = True): """ Have inner dependence from method encode_file Doesn't recomended to call it without calling the encode_file method. You can get back more bits what in really msg. Example You have n = 15, k=9 and lenght of msg in bits is 136. To decode msg u need extend bitarry to 144 bit (144⋮ 9 144⋮ 8). And it also divide by 8 without remain. 144 = 8 * 9 * 2 And after decoding, u need delete byte at the end of msg And in other case u have msg with 144 bits lenght :param file_in: :param file_out: :param make_table: function is returned the special dict. See CyclicCode.make_table() :param is_fix_err: :return: """ bit_a = ba.bitarray() bit_a.fromfile(file_in) print(f"endcode {len(bit_a)}, {bit_a}") bit_a = BaseCode.add_to_multiplicity_n(bit_a, self.n, is_to_less=True) print(f"endcode {len(bit_a)}, {bit_a}") decode = self.decode_sys(bit_a, make_table, is_fix_err=is_fix_err) key = len(decode) true_len = self.bone.setdefault(key, None) if true_len: decode = decode[:true_len] # clear the memory del self.bone[key] print(f"decode {len(decode)}, {decode}") # decode = BaseCode.add_to_multiplicity_n(decode, 8, is_to_less=True) decode.tofile(file_out)
def decode_sys(self, bit_arr: ba.bitarray, make_table, is_fix_err: bool = True): """ With correct. :param bit_arr: :param is_reshaped: :return: """ bit_arr = BaseCode.add_to_multiplicity_n(bit_arr, self.n) decoded = ba.bitarray() remain_d = None syndromes = None if is_fix_err: remain_d = self.remain_dev(bit_arr) syndromes = make_table() # print("len synd", len(syndromes)) for i in range(len(bit_arr) // self.n): i_beg = i * self.n if is_fix_err: # print(self.n_k) key = self.ba_to_str_bits(remain_d[i_beg:i_beg + self.n_k]) index_err_bit = syndromes[key] if len(index_err_bit): print(bit_arr) for index_err in index_err_bit: bit_arr[i_beg + index_err] = not bit_arr[i_beg + index_err] else: print(" " * (10 + i_beg + index_err_bit[0]) + "|" * (2)) print(bit_arr) print(index_err_bit) print(key) print(f"{index_err_bit[0]} from {self.n}", ) print(f"error fount. It index is {i_beg + index_err_bit[0]}", "\n") decoded.extend(bit_arr[i_beg + self.n_k:i_beg + self.n]) return decoded
def encode_file(self, file_in, file_out): """ :param file_in: :param file_out: :return: """ bit_a = ba.bitarray() bit_a.fromfile(file_in) len_bit_a = len(bit_a) print(f"our msg {len(bit_a)}, {bit_a}") bit_a = BaseCode.add_to_multiplicity_n(bit_a, self.k) print(f"our msg {len(bit_a)}, {bit_a}") if len(bit_a) - len_bit_a >= 8: self.bone[len(bit_a)] = len_bit_a encode = self.encody_sys(bit_a) print(f"endcode {len(encode)}, {encode}") encode.tofile(file_out)
def get_v_j(self, j) -> ba.bitarray: reverse_bit_num: str = BaseCode.int_to_str_bits(j, self.m) reverse_bit_num: ba.bitarray = ba.bitarray(reverse_bit_num) reverse_bit_num.reverse() return reverse_bit_num