#javascript #encoding #utf-8 #compression #ascii
Вопрос:
У меня есть строка, в которой, я точно знаю, есть только ASCII
буквы. JS
обрабатывает строки UTF-8
по умолчанию, поэтому это означает, что каждый символ занимает до 4 байт, что в 4 раза больше ASCII.
Я пытаюсь сжать / сохранить пробелы / получить как можно более короткую строку, используя encode
decode
функции и.
Я думал о том, чтобы представить 4 символа ASCII
в UTF-8
строке и тем самым достичь своих целей, есть ли что-нибудь подобное?
Если нет, то каков наилучший способ сжатия ASCII
строк, чтобы при кодировании и декодировании я достиг одной и той же строки?
Ответ №1:
На самом деле JavaScript кодирует программные строки в UTF-16, который использует 2 октета (16 бит) для символов Юникода в BMP (Базовая многоязычная плоскость) и 4 октета (32 бита) для символов за его пределами. Таким образом, по крайней мере внутренне символы ASCII используют 2 байта.
Есть место для упаковки двух символов ASCII в 16 бит, так как они используют только по 7 бит каждый. Кроме того, поскольку разница между 2**16
и 2**14
есть 49152
, и количество кодировок , используемых суррогатными парами в UTF-16 (предположительно) 2048
, вы должны быть в состоянии разработать схему кодирования, которая позволяет избежать диапазона кодовых точек, используемых суррогатами.
Вы также можете использовать 8-битные типизированные массивы для хранения символов ASCII, избегая при этом сложности пользовательского алгоритма сжатия.
Цель сжатия 7 — битного ASCII для использования в JavaScript в значительной степени (полностью?) в наши дни это академично, а не то, на что есть спрос. Обратите внимание, что при кодировании 7 — битного содержимого ASCII в UTF-8 (для передачи или кодирования файлов) используется только один байт для символов ASCII из-за конструкции UTF-8.
Комментарии:
1. Два примечания: «UTF-16»-это упрощение: в JS есть дублирующая строковая функция, одна из старых UCS-2 и новая UTF-16 (вы можете найти: «кодовая единица» и «кодовая точка», чтобы «явно» указать, какая интерпретация использует JS (для конкретной функции). Примечание второе: внутренне JS может использовать более оптимизированные типы (но прозрачно).
2. @GiacomoCatenazzi Глоссарий Unicode описывает разницу между кодовыми точками и единицами измерения. JavaScript был написан для UCS-2, который объясняет, почему
String.prototype
такие методы, какcharAt
иcharCodeAt
, работают с единицами кода иstring.length
возвращают количество единиц кода в строке, а не символов.String.prototype.codePointAt
Метод был частью расширения UCS-2 до строковой кодировки UTF-16, но аргумент метода указан в кодовых единицах. Я сомневаюсь, что оптимизация JavaScript доходит до изменения 16-битного размера единиц строкового кода.3. Я не знаю об оптимизации, но Python делает это (и Python не так сильно оптимизирован, как JS, и оба обмениваются идеями реализации).
Ответ №2:
Если вы хотите использовать 1 байт на символ, вы можете просто использовать байт. Уже существует функция для преобразования в строку из байтов.