Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.64 KB | None | 0 0
  1. import random
  2.  
  3. # длина блока кодирования
  4. CHUNK_LENGTH = 26
  5.  
  6. # проверка длины блока
  7. #assert not CHUNK_LENGTH % 8, 'Длина блока должна быть кратна 8'
  8.  
  9. # вычисление контрольных бит
  10. CHECK_BITS = [i for i in range(1, CHUNK_LENGTH + 1) if not i & (i - 1)]
  11. LEN_CHECK_BITS = len(CHECK_BITS)
  12.  
  13. def chars_to_bin(chars):
  14.     """
  15.    Преобразование символов в бинарный формат
  16.    """
  17.     #assert not len(chars) * 8 % CHUNK_LENGTH, 'Длина кодируемых данных должна быть кратна длине блока кодирования'
  18.     return ''.join([bin(ord(c))[2:].zfill(8) for c in chars])
  19.  
  20. def octet_to_bin(octet):
  21.     return ''.join(bin(int(octet))[2:].zfill(8))
  22.  
  23. def bin_text_to_octet_list(bin_text):
  24.     answer = []
  25.     for octet in chunk_iterator(bin_text, 8):
  26.         answer.append(int(octet, 2))
  27.     return answer
  28.  
  29. def chunk_iterator(text_bin, chunk_size=CHUNK_LENGTH):
  30.     """
  31.    Поблочный вывод бинарных данных
  32.    """
  33.     for i in range(len(text_bin)):
  34.         if not i % chunk_size:
  35.             yield text_bin[i:i + chunk_size]
  36.  
  37.  
  38. def get_check_bits_data(value_bin):
  39.     """
  40.    Получение информации о контрольных битах из бинарного блока данных
  41.    """
  42.     check_bits_count_map = {k: 0 for k in CHECK_BITS}
  43.     for index, value in enumerate(value_bin, 1):
  44.         if int(value) != 0:
  45.             bin_char_list = list(bin(index)[2:].zfill(8))
  46.             bin_char_list.reverse()
  47.             bin_char_list = bin_char_list[:LEN_CHECK_BITS]
  48.             for degree in [2 ** int(i) for i, x in enumerate(bin_char_list) if int(x) != 0]:
  49.                 check_bits_count_map[degree] += 1
  50.     check_bits_value_map = {}
  51.     for check_bit, count in check_bits_count_map.items():
  52.         check_bits_value_map[check_bit] = 0 if not count % 2 else 1
  53.     return check_bits_value_map
  54.  
  55.  
  56. def set_empty_check_bits(value_bin):
  57.     """
  58.    Добавить в бинарный блок "пустые" контрольные биты
  59.    """
  60.     for bit in CHECK_BITS:
  61.         value_bin = value_bin[:bit - 1] + '0' + value_bin[bit - 1:]
  62.     return value_bin
  63.  
  64.  
  65. def set_check_bits(value_bin):
  66.     """
  67.    Установить значения контрольных бит
  68.    """
  69.     value_bin = set_empty_check_bits(value_bin)
  70.     check_bits_data = get_check_bits_data(value_bin)
  71.     for check_bit, bit_value in check_bits_data.items():
  72.         value_bin = '{0}{1}{2}'.format(value_bin[:check_bit - 1], bit_value, value_bin[check_bit:])
  73.     return value_bin
  74.  
  75.  
  76. def get_check_bits(value_bin):
  77.     """
  78.    Получить информацию о контрольных битах из блока бинарных данных
  79.    """
  80.     check_bits = {}
  81.     for index, value in enumerate(value_bin, 1):
  82.         if index in CHECK_BITS:
  83.             check_bits[index] = int(value)
  84.     return check_bits
  85.  
  86.  
  87. def exclude_check_bits(value_bin):
  88.     """
  89.    Исключить информацию о контрольных битах из блока бинарных данных
  90.    """
  91.     clean_value_bin = ''
  92.     for index, char_bin in enumerate(list(value_bin), 1):
  93.         if index not in CHECK_BITS:
  94.             clean_value_bin += char_bin
  95.  
  96.     return clean_value_bin
  97.  
  98.  
  99. def set_errors(encoded):
  100.     """
  101.    Допустить ошибку в блоках бинарных данных
  102.    """
  103.     result = ''
  104.     for chunk in chunk_iterator(encoded, CHUNK_LENGTH + len(CHECK_BITS)):
  105.         num_bit = random.randint(1, len(chunk))
  106.         chunk = '{0}{1}{2}'.format(chunk[:num_bit - 1], int(chunk[num_bit - 1]) ^ 1, chunk[num_bit:])
  107.         result += (chunk)
  108.     return result
  109.  
  110.  
  111. def check_and_fix_error(encoded_chunk):
  112.     """
  113.    Проверка и исправление ошибки в блоке бинарных данных
  114.    """
  115.     check_bits = get_check_bits_data(encoded_chunk)
  116.     error_index = sum([x for x in check_bits.keys() if check_bits[x] != 0])
  117.     if error_index:
  118.         encoded_chunk = '{0}{1}{2}'.format(encoded_chunk[:error_index - 1], int(encoded_chunk[error_index - 1]) ^ 1, encoded_chunk[error_index:])
  119.     return encoded_chunk
  120.  
  121.  
  122. def get_diff_index_list(value_bin1, value_bin2):
  123.     """
  124.    Получить список индексов различающихся битов
  125.    """
  126.     diff_index_list = []
  127.     for index, char_bin_items in enumerate(zip(list(value_bin1), list(value_bin2)), 1):
  128.         if char_bin_items[0] != char_bin_items[1]:
  129.             diff_index_list.append(index)
  130.     return diff_index_list
  131.  
  132. def encode_binary(text_bin):
  133.     result = ''
  134.     for chunk_bin in chunk_iterator(text_bin):
  135.         chunk_bin = set_check_bits(chunk_bin)
  136.         result += chunk_bin[::-1]
  137.     return result
  138.  
  139. def encode(source):
  140.     """
  141.    Кодирование данных
  142.    """
  143.     text_bin = chars_to_bin(source)
  144.     while len(text_bin) % CHUNK_LENGTH != 0:
  145.         text_bin += '0'
  146.     return encode_binary(text_bin)
  147.  
  148. def decode(encoded, fix_errors=True):
  149.     """
  150.    Декодирование данных
  151.    """
  152.     decoded_value = ''
  153.     fixed_encoded_list = []
  154.     for encoded_chunk in chunk_iterator(encoded, CHUNK_LENGTH + len(CHECK_BITS)):
  155.         if fix_errors:
  156.             encoded_chunk = check_and_fix_error(encoded_chunk[::-1])
  157.         fixed_encoded_list.append(encoded_chunk)
  158.  
  159.     clean_chunk_list = []
  160.     for encoded_chunk in fixed_encoded_list:
  161.         encoded_chunk = exclude_check_bits(encoded_chunk)
  162.         clean_chunk_list.append(encoded_chunk)
  163.  
  164.     clear_text = ''.join(clean_chunk_list)
  165.  
  166.     for clean_char in [clear_text[i:i + 8] for i in range(len(clear_text)) if not i % 8]:
  167.         decoded_value += chr(int(clean_char, 2))
  168.     return decoded_value
  169.  
  170. def gui():
  171.     source = input('Укажите текст для кодирования/декодирования:')
  172.     print('Длина блока кодирования: {0}'.format(CHUNK_LENGTH))
  173.     print('Контрольные биты: {0}'.format(CHECK_BITS))
  174.     encoded = encode(source)
  175.     octet_list = bin_text_to_octet_list(encoded)
  176.     print('Закодированные данные: {0}'.format(encoded))
  177.     print(sum(map(int, list(encoded))))
  178.     while len(encoded) % CHUNK_LENGTH != 0:
  179.         encoded += '0'
  180.     decoded = decode(encoded)
  181.     print('Результат декодирования: {0}'.format(decoded))
  182.     encoded_with_error = set_errors(encoded)
  183.     print('Допускаем ошибки в закодированных данных: {0}'.format(encoded_with_error))
  184.     diff_index_list = get_diff_index_list(encoded, encoded_with_error)
  185.     print('Допущены ошибки в битах: {0}'.format(diff_index_list))
  186.     decoded = decode(encoded_with_error, fix_errors=False)
  187.     print('Результат декодирования ошибочных данных без исправления ошибок: {0}'.format(decoded))
  188.     decoded = decode(encoded_with_error)
  189.     print('Результат декодирования ошибочных данных с исправлением ошибок: {0}'.format(decoded))
  190.  
  191. def task_solver():
  192.     octets = [130, 41, 86, 38, 143, 145, 32, 150, 196, 206, 68, 82, 32, 104, 112, 161, 80, 27, 77, 88, 208, 204, 1, 12, 76, 140, 2, 94, 2, 35, 7, 0, 191, 129, 64];
  193.     text_bin = ''.join([octet_to_bin(x) for x in octets])
  194.     while len(text_bin) % CHUNK_LENGTH != 0:
  195.         text_bin += '0'
  196.     decoded = decode(text_bin, fix_errors=True)
  197.     print(decoded)
  198.  
  199. if __name__ == '__main__':
  200.     task_solver()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement