Сжатие UTF-8 (или другого 8-битного кодирования) до 7 или менее бит - PullRequest
2 голосов
/ 03 декабря 2009

Я хочу взять файл, закодированный в UTF-8, который не использует более 128 различных символов, а затем переместить его в 7-битную кодировку, чтобы сэкономить 1/8 места. Например, если у меня есть текстовый файл размером 16 МБ, в котором используются только первые 128 символов (ascii), я хотел бы уменьшить лишний бит, чтобы уменьшить размер файла до 14 МБ.

Как бы я поступил так?

Кажется, что для этого не существует бесплатной или проприетарной программы, поэтому я подумал, что могу попробовать сделать простую (если неэффективную) программу.

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

Так что если файл выглядел так (я буду использовать десятичный пример, потому что я стараюсь не думать в шестнадцатеричном формате)

127 254 025 212 015 015 132 ... Это станет

001 002 003 004 005 005 006

Если 127 сопоставлено с 001, 254 сопоставлено с 005 и т. Д.

Хотя я не совсем уверен в паре вещей.

  1. Этого будет достаточно, чтобы на самом деле сократить размер файла? У меня плохое предчувствие, что это просто оставило бы дополнительный 0 в двоичной строке - 11011001 может быть сопоставлен с 01000001, а не 1000001, и я не буду на самом деле экономить место. Если это произойдет, как мне избавиться от нуля?
  2. Как открыть файл для чтения / записи в двоичном / десятичном / шестнадцатеричном формате, а не только в текстовом формате? Я в основном работал с Python, но могу перепутать C, если мне нужно.

Спасибо.

Ответы [ 6 ]

18 голосов
/ 03 декабря 2009

Просто используйте сжатие gzip и сэкономьте 60-70% с усилием 0%!

6 голосов
/ 03 декабря 2009

Вы понимаете, что файлы делятся на байты? Таким образом, если бы вы сделали это, у вас было бы 7 бит первой буквы в байтах 1, плюс 1 бит второй буквы, затем во втором байте у вас было бы 6 бит второй буквы и 2 бита в-третьих, так далее. Это будет выглядеть так:

|AAAAAAAB|BBBBBBCC|CCCCCDDD|DDDDEEEE|EEEFFFFF|FF...
 \------/ \------/ \------/ \------/ \------/
   byte     byte     byte     byte     byte
3 голосов
/ 03 декабря 2009

Ваша идея находится на правильном пути, но нуждается в доработке. Если вас интересует этот вид сжатия данных, вы можете изучить кодирование Хаффмана . Это простой метод сжатия данных, который используется во многих реальных ситуациях.

Я могу порекомендовать Книга сжатия данных Марка Нельсона, которая является отличным введением в методы сжатия данных.

1 голос
/ 03 декабря 2009

Ваша идея вряд ли сработает. Если вы записываете байт 0x05 в файл, байт записывается, все 8 бит - с начальными нулями. Чтобы действительно выполнить то, что вам нужно, вы можете кодировать каждые 8 ​​байтов в 7 байтов (так как вам нужно только 8 * 7 бит для кодирования 8 значений). Один из подходов состоит в том, чтобы сохранить 7 значений в 7 младших битах их байтов и распределить 8-й байт по 7 битам MS.

Что касается Python, открытие файла в двоичном режиме записи - open(filename, 'wb'). Вам также необходимо узнать о битовых операциях для упаковки байтов, как описано выше.

Просто небольшой пример:

>>> a = 0x03
>>> b = 0x59
>>> c = ((a & 0x1) << 7) | b
>>> hex(c)
'0xd9'
>>> 

Это помещает младший бит a в MSBit, равный c, а остальная часть c является значением b.

Я уверен, что вы можете взять его отсюда.

0 голосов
/ 03 декабря 2009

"это просто оставило бы дополнительный 0 в двоичной строке - 11011001 может быть сопоставлен с 01000001, а не 1000001, и я не буду на самом деле экономить место."

Правильно. Ваш план ничего не сделает.

0 голосов
/ 03 декабря 2009

То, что вам нужно, это UTF-7.

Редактировать: Преимущество UTF-7 состоит в том, что «раздутые» специальные символы раздуты, поэтому, если во входных данных специальные символы встречаются редко, вы получите намного меньше байтов, чем просто преобразовав UTF-8 в 7-битный , Вот для чего нужен UTF-7.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...