Эффективный способ кодирования ASCII UTF-8 - PullRequest
2 голосов
/ 02 апреля 2010

Я ищу простой и эффективный способ хранения строк UTF-8 в ASCII-7. Под эффективным я имею в виду следующее:

  • все буквенно-цифровые символы ASCII на входе должны оставаться такими же буквенно-цифровыми символами ASCII на выходе
  • результирующая строка должна быть как можно короче
  • операция должна быть обратимой без потери данных
  • результирующая строка ASCII должна быть без учета регистра
  • не должно быть никаких ограничений на длину ввода
  • весь диапазон UTF-8 должен быть разрешен

Моя первая идея состояла в том, чтобы использовать Punycode (IDNA), так как он соответствует первым четырем требованиям, но он терпит неудачу в последних двух.

Кто-нибудь может порекомендовать альтернативную схему кодирования? Еще лучше, если есть какой-то код, доступный для просмотра.

Ответы [ 6 ]

4 голосов
/ 02 апреля 2010

UTF-7 или, чуть менее прозрачный, но более распространенный, цитируемый для печати .

все символы ASCII на входе должны оставаться символами ASCII на выходе

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

2 голосов
/ 02 апреля 2010

Поскольку ASCII охватывает весь диапазон 7-битных значений, схема кодирования, которая сохраняет все символы ASCII, имеет длину 7 бит и кодирует полный диапазон Unicode, невозможна.

Отредактировано, чтобы добавить:

Думаю, теперь я понимаю ваши требования. Вы ищете способ кодирования строк UTF-8 в семибитном коде, в котором, если эта закодированная строка была интерпретирована как текст ASCII, тогда регистр буквенных символов может быть произвольно изменен, и все же декодированная строка быть побайтным идентичным оригиналу.

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

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

1 голос
/ 05 декабря 2011

Если вы говорите о нестандартных схемах - MECE

0 голосов
/ 02 мая 2013

Punycode используется для IDNA, но вы можете использовать его вне ограничений, наложенных им

По сути, Punycode не соответствует вашим последним 2 требованиям:

>>> import sys
>>> _ = ("\U0010FFFF"*10000).encode("punycode")
>>> all(chr(c).encode("punycode") for c in range(sys.maxunicode))
True

(для idna python предоставляет другую одноименную кодировку)

очевидно, что если вы не присваиваете имени вводу входные данные, закодированная строка больше не является строго чувствительной к регистру ... но если вы вводите только нижний регистр (или если вас не волнует декодированный регистр), вам следует хорошо идти

0 голосов
/ 03 апреля 2010

Это зависит от распределения символов в ваших строках.

Quoted-printable подходит для строк в основном ASCII, потому что нет никаких накладных расходов, кроме '=' и управляющих символов. Однако не-ASCII-символы занимают неэффективные 6-12 байт каждый, поэтому, если у вас их много, вместо этого вы должны рассмотреть UTF-7 или Base64.

0 голосов
/ 02 апреля 2010

Кодировка URL или ссылки на цифровые символы - это два возможных варианта.

...