Мы часто слышим обычный текстовый формат и двоичное кодирование, что такое обычный текст и что такое двоичное? Чтобы проиллюстрировать на примере. Создайте новый файл hello.txt со следующим содержимым:
hello, world
Этот файл имеет 12 байт:
С помощью Node.js вы можете увидеть, какое исходное двоичное хранилище этого файла находится на жестком диске.Следующий код:
let fs = require("fs");
// 读取原始二进制内容
let buffer = fs.readFileSync("hello.txt");
console.log(buffer);
После запуска консоль выводит 12 байт двоичного содержимого (отображается в шестнадцатеричном формате):
<Buffer 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64>
Обращаясь к таблице ASCII, мы обнаруживаем, что эти числа являются просто кодами ASCII, соответствующими английскому языку, как показано на следующем рисунке:
Если этот текстовый файл читается в utf-8:
let fs = require("fs");
let text = fs.readFileSync("hello.txt", "utf-8");
console.log(text);
На выходе текст:
Здесь есть два совершенно разных результата вывода, но на самом деле, будь то простой текстовый файл или бинарный файл, жесткий диск или память хранит все 0101, в зависимости от того, как вы это интерпретируете, или как это декодируете. (Просто обычный текст, на который мы обычно ссылаемся, относится к формату, который может быть декодирован в читаемый текст, а формат двоичного файла относится к таким файлам, как изображения, которые нельзя декодировать с помощью текста, такого как UTF-8.)
Как показано ниже:
Если считается, что это UTF-8, кодировка может соответствовать тексту. Как появился шрифт текста? Он находится внутри файла шрифта, в котором хранится форма каждого символа в векторном формате svg. Что такое кодировка UTF/UTF-8?
Кодировка UTF
1 байт может представлять всего 256 символов от 0 до (2^8 – 1). ASCII использует 7 бит для представления 128 символов, что соответствует требованиям современного английского языка. Как следует использовать специальные символы, азиатские языки и Emoj? представлены? Мы следуем описанному выше методу, чтобы увидеть, что хранятся в следующих файлах, содержащих символы китайского языка и эмодзи:
we 发 财 🤑
Как показано ниже:
Среди них кодировка пробела 20. Вы можете видеть, что английский по-прежнему занимает 1 байт, китайский использует 3 байта, а эмодж использует 4 байта. Как он узнает, сколько байтов он должен считывать каждый раз? Как показано ниже:
Если байт начинается с 0, это означает, что этот байт представляет символ, если он начинается с 3 единиц, это означает, что этот символ занимает 3 байта, а сколько единиц означает, сколько байтов занимает текущий символ. Это функция хранения UTF-8.UTF определяет количество каждого символа, а UTF-8 определяет, как должны храниться символы. отофициальный сайт юникодаМожно обнаружить, что кодировка UTF для «I» — 6211, как показано на следующем рисунке:
Как 6211 становится кодировкой utf-8? Потому что 6211 попадает в следующий диапазон:
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
Итак, это выглядит так:
«Мой» utf-8 — это E6 88 91, вы можете сравнить результат encodeURIComponent:
Можно сказать, что utf-8 делает utf реализованным, а utf-8 является наиболее широко используемым методом кодирования текста в Интернете. Помимо utf-8 и utf-16, отношение преобразования между ними и utf следующее:
UTF-8
U+ 0000 ~ U+ 007F: 0XXXXXXX
U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+10FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
UTF-16
U+0000 - U+FFFF xxxxxxxx xxxxxxxx
U+10000 - U+10FFFF 110110xx xxxxxxxx 110111xx xxxxxxxx
Преимущество utf-8 в том, что английскому нужен только один байт, а китайскому - 3 байта.Преимущество utf-16 в том, что длина кодировки фиксированная, китайскому нужно всего два 2 байта, а английскому тоже нужно два слова Фестиваль. Следовательно, более выгодно использовать кодировку utf-8 для веб-страниц на английском языке, а кодировку utf-16 для китайских веб-страниц должно быть более выгодно. Потому что большинство китайцев используют коды от U+0000 до U+FFFF. Для таких символов, как Emoj, которые обычно не используются в конце, как utf-8, так и utf-16 требуется 4 байта. При этом utf-32 — это фиксированные 4 байта.
Полную кодировку UTF можно найти на официальном сайте, вот некоторые символы и диапазоны их кодировки, как показано на следующем рисунке:
Китайские иероглифы от 4E00 до 9FFF, их около 20 000. Кодировка FXXXX и 10XXXX предназначена для настройки, например, может использоваться для шрифтов значков, но шрифты значков обычно не используют этот диапазон, а используют более короткие кодировки, которые просто сопоставляются с другими обычными наборами символов, такими как традиционные символы, поэтому в качестве В результате система будет использовать шрифт по умолчанию перед загрузкой шрифта значка, и на странице сначала будут отображаться традиционные китайские символы, а затем восстановлен значок. Эта проблема возникает на телефонах Android.
Мы можем использовать кодировку UTF непосредственно в html, например:
Затем отобразится веб-страница:
Это также называется html-сущностью (сущностью), обычно используемой для экранирования специальных символов или шрифтов значков.
Затем мы поговорим об искаженных символах.
искаженный
Откройте двоичный файл в текстовом редакторе, например файл изображения:
Многие текстовые редакторы по умолчанию используют кодировку utf-8, например submlime:
Если каждый код соответствует символу, он будет отображаться, но эти символы при подключении выглядят беспорядочно, поэтому он «искажается».
Вот реальная проблема с искажением.Для сжатых пакетов Windows имя распакованного файла на Mac обычно искажено, как показано на рисунке ниже.Почему это?
Кодировка окон по умолчанию — ANSI, и следующие кодировки можно сохранить с помощью текстового редактора, входящего в состав Windows:
ANSI в соответствии с локалью, упрощенный китайский использует GBK. Что такое ГБК? GBK — местная кодировка китайского языка. Например, кодировка GBK для буквы «I» — CED2. Первоначальный стандарт кодирования китайского языка — GB2312, который включает более 6000 часто используемых китайских иероглифов. Позже был выпущен GBK, и традиционные китайские иероглифы были включен, а позже был выпущен GB18030, включающий языки этнических меньшинств.Различные отношения кодирования показаны на следующем рисунке:
Но программное обеспечение Mac обычно использует utf-8, китайский должен быть 3 байта, но сейчас только 2 байта, что не правильно, поэтому при распаковке он становится другим символом, что выглядит искаженным. На компьютерах Mac можно установить программу под названием unarchive, в которой есть алгоритмы автоматического определения кодировки символов:
С распакованными именами файлов проблем нет. Кроме того, многие редакторы кода обычно используют по умолчанию utf-8.Текст, сохраненный в текстовом редакторе, который поставляется с Windows, будет искажен при открытии в этом редакторе:
Когда выбран правильный метод кодирования, отображение будет нормальным:
Также часто встречается проблема с кодировкой текста, то есть возврат каретки и перевод строки.
возврат каретки и перевод строки
Метод разрыва строки Sublime по умолчанию основан на системных настройках, как показано в следующих настройках Sublime:
Из его комментариев также видно, что Windows использует CRLF, а Unix-системы используют LF:
CR: Возврат каретки (возврат каретки\r)
LF: перевод строки (перевод строки\n)
Другими словами, новая строка окон — это \r\n, а система Unix, такая как Mac, использует \n. В чем разница между возвратом каретки и переводом строки? Enter означает перемещение курсора в начало строки, а новая строка означает перемещение курсора на следующую строку. Если вы запустите следующий код в Node.js:
console.log("hello, world\rgoodbye, world");
Тогда будет выведено «до свидания, мир»:
«привет, мир» перезаписывается, это то, что делает возврат каретки. Позже, в целях экономии места, новая строка Unix будет только \n.
"\r" будет отображаться как ^M в git:
Иногда возникает другая проблема: при привязке хоста сообщение, скопированное из QQ, вставляется в файл хоста, в MAC может быть больше \r и это не подействует, а в винде может быть меньше \r проблем. может выглядеть как обычный разрыв строки в вашем редакторе.
Поговорим о длине строки.
длина строки
В строках Java и JS используется кодировка UTF-16, поскольку она имеет преимущество относительно фиксированной длины, в отличие от UTF-8, которая может изменять количество байтов от 1 до 4. Как показано ниже:
Длина английского и китайского языков равна 1, а длина Emoj равна 2, потому что единица длины составляет 2 байта как 1, а длина Emoj составляет 4 байта, поэтому длина равна 2.
Вы можете использовать charCodeAt для возврата кодировки utf текущего символа:
Если вы хотите определить китайский язык, вы можете использовать регулярные выражения, чтобы увидеть, попадает ли текущий символ в диапазон китайской кодировки:
В Mysql, если тип поля VARCHAR(10), он может хранить до 10 английских или 10 китайских символов.Если это поле использует кодировку utf-8 по умолчанию, оно должно учитывать 10 * 3 = 30 байт, если используется кодировка GBK, то необходимо использовать 10 * 2 = 20 байт.
тег метакодировки
Обычно мы добавляем мета-кодировку в тег заголовка страницы, указывающий метод кодирования текущей страницы:
<meta charset="utf-8">
В html4 это написано так:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Эти два работают одинаково, но последний устарел. Какая польза от этого кода?
В качестве исследования используется code.html:
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
你好world
</body>
</html>
Затем пишем простейший сервер на Node.js:
let http = require("http");
let fs = require("fs");
http.createServer((req, res) => {
let content = fs.readFileSync("./code.html", "utf-8");
console.log(req.url);
res.end(content);
}).listen("8125", err => {
if (err) {
console.log(err);
} else {
console.log("Server start, listening on http://localhost:8125");
}
});
Запустите, а затем посетите localhost:8125, страница отображается нормально:
Теперь я меняю кодировку на gbk:
<meta charset="gbk">
Затем снова обновите страницу, это ненормально:
Но если я установлю кодировку заголовка ответа Content-Type на utf-8 на сервере Node.js:
res.setHeader("Content-Type", "text/html; charset=utf-8");
Этот заголовок ответа можно увидеть в консоли браузера:
Независимо от того, какая кодировка установлена в метатеге, страница может отображаться нормально.
Таким образом, согласно нашему наблюдению, метатег будет работать только в том случае, если в заголовке ответа http не задана кодировка.
В этой статье обсуждается взаимосвязь между utf/utf-8/utf-16.utf — это международный стандарт, определяющий кодировку каждого символа, а utf-8/utf-16 определяет, как utf хранится и читается. в том, что он более выгоден для английского и экономит место, а utf-16 более выгоден для китайского. Но если западные страны используют utf-8, а затем восточные страны используют utf-16, то интернет может быть запутанным, поэтому мы все еще используем utf-8 с точки зрения единых стандартов. Также обсуждалась проблема кодировки GBK и искаженных символов.Если символ хранится в одной кодировке, но читается в другой кодировке, он не будет соответствовать исходным символам, и будут искаженные символы.условие. Кроме того, поскольку длина кодировки utf-16 относительно фиксирована, JS и Java используют utf-16 в качестве кодировки своих строк в памяти. Согласно эксперименту, тег charset мета работает, когда не задана кодировка заголовка ответа.
Короче говоря, кодировка символов — это большая тема, в этой статье в основном обсуждается та ее часть, которая имеет большое отношение к Сети, а также перечисляются некоторые проблемы, с которыми мы обычно сталкиваемся. Я считаю, что после прочтения этой статьи вы должны лучше понять кодировку текста.