Существует ли 8-разрядная кодовая страница (CP -####), на которой определен каждый байт?

#python #codepages

Вопрос:

В настоящее время я пытаюсь создать код для алгоритма сжатия данных. Моя цель состоит в том, чтобы взять файл и прочитать его, преобразовать в двоичный эквивалент, а затем сохранить его в выходной текстовый файл.

Например: Допустим, мой ввод — «Привет, мир».,

тогда я хочу, чтобы в моем выводе было «0100100001100101011011000110110001101111001000000101011101101111011110111100110110001100100».

Этот код успешно выполняет это для большинства сообщений. Однако у меня есть файл с необходимым байтом информации «10000001». В CP-1252 это соответствует неопределенному символу.

Есть ли 8-разрядная кодовая страница, которую я могу использовать в строке 9, символ 51 моего кода, который использует все 256 возможных кодов, чтобы избежать этой ошибки?

 from datetime import datetime
now = datetime.now()

#makes a file with a unique timestamp in the name
stamp = now.strftime("%H%M%S")
f = open("requests"   str(stamp)   ".txt", "w")

#opens desired input file in read mode
text_file = open("videointxt", mode="r", encoding=None)
                                                  ^
#read whole file to a string
data = text_file.read()

#takes the message converts it to its binary equivakent, and then writes it to the output file
res = ''.join(format(ord(i), '08b') for i in data)
print(res, file=f)


f.close
 

Комментарии:

1. Ваш вывод представляет собой строку обычных ASCII "1" s и "0" s. Неясно, где у вас возникли проблемы с наборами символов.

2. Просто хочу отметить, encoding=None что декодирование не «отключается» при чтении из файла. Он просто указывает open использовать кодировку по умолчанию вашей платформы, которая может не совпадать с тем, что на самом деле используется файлом для кодирования вложенного текста. Кроме того, если вы хотите прочитать необработанные байты, откройте файл в двоичном режиме ( mode='rb' ) и интерпретируйте байты самостоятельно.

Ответ №1:

Ваша проблема не в кодовой странице как таковой. Ваша проблема в том, что вы пытаетесь интерпретировать двоичную информацию в виде символов. В python3.x строки являются Юникодом. Чтобы Python мог считывать данные в виде строки, ему необходимо знать отображение значений в символы, т. е. кодировку. Если вы просто хотите загрузить необработанные данные без их интерпретации, вы, вероятно, захотите предварительно выполнить чтение байта и пропустить передачу кодировки.

 - text_file = open("videointxt", mode="r", encoding=None)
  text_file = open("videointxt", mode="rb")
 

Переменная text_file теперь будет иметь тип байтов вместо типа строки, поэтому вам нужно будет изменить способ взаимодействия с ней, но это означает, что вам не нужно возиться с кодировками, пока вы не решите, как вы хотите отображать информацию на экране.

Лично я бы предложил отображать выходные данные в шестнадцатеричном формате, а не в двоичном.


Пожалуйста, обратите внимание, что текстовые данные на диске уже имеют двоичный формат. При хранении двоичного эквивалента на диске нет никаких преимуществ для хранения. Процесс преобразования символов в двоичный код и записи на диск является обратным тому, что произошло, когда файл был прочитан с самого начала.

Как говорит @chepner, ваш код создает строку из символов » 0 » и «1», что увеличит общий размер файла в 8 раз.

Если вы работаете на терминале Linux, вы можете убедиться в этом сами:

 # my_script.py
with open('tmp', 'rb') as f:
    data = file.read()
    print(''.join(format(i, '08b') for i in data))
 
 $ echo -n 'a' > tmp
$ xxd -b tmp
00000000: 01100001                                               a
$ python my_script.py > tmp
$ xxd -b tmp
00000000: 00110000 00110001 00110001 00110000 00110000 00110000  011000
00000006: 00110000 00110001                                      01
 

Обратите внимание, как вы увеличили размер файла с 1 байта до 8, потому что вместо хранения » a «в виде 1 байта данных вы сохраняете 8 экземпляров символов «0» и «1».

Комментарии:

1. Это очень плохой способ работы с текстом. Байты будут непригодны для использования до тех пор, пока они не будут преобразованы в текст. Когда это произойдет, проблема будет точно такой же — необходимо указать кодировку. Если только текст не отображается в виде шестнадцатеричного значения, которое все еще является своего рода кодировкой. Если кодировка файла известна, его можно использовать open как в любом другом месте, так и в любом другом

2. @PanagiotisKanavos Ты на 100% прав. Моя интерпретация операции заключается в том, что они хотят прочитать файл, «преобразовать его в двоичный файл» и записать его обратно на диск. Я думаю, что основная проблема заключается не в том, читается ли строка как символы или двоичный файл, а в том, что строковые данные на диске еще не являются двоичным форматом. Я хотел бы услышать любые предложения о том, как я могу лучше это объяснить. 🙂

3. Основная причина, по которой я хотел записать формат ASCII исходного двоичного файла, заключалась в том, чтобы затем python произвел битовые манипуляции с теперь выведенным файлом, а затем перекомпилировал теперь обработанный двоичный файл ASCII обратно в обычный двоичный файл. Этот шаг для записи входного файла в двоичный файл ASCII предназначен для алгоритма сжатия данных для его чтения. Тем не менее, я думаю, что если у меня просто будет код, просто прочитайте двоичный файл, разбейте его на более мелкие фрагменты, поместите фрагменты в словарь, то я думаю, что смогу сделать то же самое без необходимости преобразования в ASCII-двоичный шаг. Спасибо за помощь!