предисловие
Эта статья включена вПродвинутые основы интерфейсаКолонка, добро пожаловать, чтобы следовать и собирать, прошлые классики:
- [Галантерейные товары] Сколько из этих передовых функций инструментов у вас есть? 500+ star
- 3000 слов, и я не написал Function.prototype.call 200+ star
- Те функции, с которыми вы знакомы, но не знакомы 200+ star
- Вы действительно знаете разницу между этими 16 нативными функциями и свойствами? Тщательно собранные, передовые базовые знания, быстро упаковать и забрать 100+ star
Коллекция не ЗВЕЗДА является изгоем! какие
контур
Удобно читать на мобильном:
- Применение Base64 во внешнем интерфейсе
- Источник кодирования данных Base64
- Значение кодировки Base64 64
- Преимущества и недостатки кодировки Base64
- Некоторые компьютерные и интерфейсные основы
- ASCII, Юникод, UTF-8
- Кодирование и декодирование Base64
- Другие зрелые решения
- напиши в конце
Применение Base64 во внешнем интерфейсе
Кодировка Base64, вы должны знать, давайте взглянем на некоторые из ее распространенных приложений во внешнем интерфейсе:
Конечно, большинство сцен основано наData URLs
Создание изображения холста
холстtoDataURLВы можете преобразовать содержимое холста холста в формат кодировки base64, включая отображение изображения.data URI.
const ctx = canvasEl.getContext("2d");
// ...... other code
const dataUrl = canvasEl.toDataURL();
// data:image/png;base64,iVBORw0KGgoAAAANSUhE.........
Я думаю, вы рисуете, к вам присоединяются новые пользователи, чтобы получить самый последний интерфейс рисования, вы также можете передавать сообщения в формате Base64.
файл прочитан
FialeReaderreadAsDataURLЗагруженный файл можно преобразовать в URI данных в формате base 64. Более распространенным сценарием является вырезание и загрузка пользовательских аватаров.
function readAsDataURL() {
const fileEl = document.getElementById("inputFile");
return new Promise((resolve, reject) => {
const fd = new FileReader();
fd.readAsDataURL(fileEl.files[0]);
fd.onload = function () {
resolve(fd.result);
// data:image/png;base64,iVBORw0KGgoAAAA.......
}
fd.onerror = reject;
});
}
jwt
jwt состоит из трех частей: заголовка, полезной нагрузки и подписи.После декодирования первых двух их можно увидеть в виде открытого текста. братьСильнейший JWT на национальном сервере генерирует Токен для проверки входа, после прочтения которого вы гарантированно научитесь!Токен внутри проверен.
Изображения веб-сайтов и небольшие изображения
Оптимизация иконок мобильного сайта
<link rel="icon" href="data:," />
<link rel="icon" href="data:;base64,=" />
Что касается того, как получить это значениеdata:,
из:
<canvas height="0" width="0" id="canvas"></canvas>
<script>
const canvasEl = document.getElementById("canvas");
const ctx = canvasEl.getContext("2d");
dataUrl = canvasEl.toDataURL();
console.log(dataUrl); // data:,
</script>
маленькая картинка
У этого есть много сцен, таких как теги img, фоновые изображения и т. д.
тег img:
<img src="data:image/png;base64,iVBORw0KGgoAAAA......." />
css фоновое изображение:
.bg{
background: url(data:image/png;base64,iVBORw0KGgoAAAA.......)
}
Простое шифрование данных
Конечно, это не очень хороший способ, но, по крайней мере, он затрудняет вам интерпретацию.
const username = document.getElementById("username").vlaue;
const password = document.getElementById("password").vlaue;
const secureKey = "%%S%$%DS)_sdsdj_66";
const sPass = utf8_to_base64(password + secureKey);
doLogin({
username,
password: sPass
})
SourceMap
Позаимствуйте кусок кода у Ruan Dashen, обратите внимание на поле Mappings, которое на самом деле является содержимым формата кодировки bas64.Конечно, если вы попытаетесь решить его напрямую, это не удастся.
{
version : 3,
file: "out.js",
sourceRoot : "",
sources: ["foo.js", "bar.js"],
names: ["src", "maps", "are", "fun"],
mappings: "AAgBC,SAAQ,CAAEA"
}
Для конкретной реализации, пожалуйста, смотрите официальныйbase64-vlq.jsдокумент.
Обфусцированный зашифрованный код
Известная библиотека обфускации кода,javascript-obfuscator, который также имеет несколько кодов base64, давайте взглянем на варианты:
webpack-obfuscatorТакже на основе его упаковки.
--string-array-indexes-type '<list>' (comma separated) [hexadecimal-number, hexadecimal-numeric-string]
--string-array-encoding '<list>' (comma separated) [none, base64, rc4]
--string-array-index-shift <boolean>
--string-array-wrappers-count <number>
--string-array-wrappers-chained-calls <boolean>
разное
Сертификаты открытого ключа X.509, ключи SSH github, файлы mht, вложения электронной почты и т. д. — все они имеют тень Base64.
Источник кодировки данных Base64
Ранние протоколы передачи почты основывались на тексте ASCII и плохо работали с двоичными файлами, такими как изображения и видео. ASCII в основном используется для отображениясовременный английский, пока только определил128символов, включая управляющие символы и отображаемые символы. Чтобы решить вышеуказанные проблемы, родилась кодировка Base64.
Base64 — это кодек, основная функция которого заключается не в обеспечении безопасности, а в обеспечении безошибочной передачи контента между различными шлюзами, это основная функция кодирования Base64.
Помимо кодировки данных Base64, на самом делеКодировка данных Base32, кодировка данных Base16, видетьRFC 4648.
Значение кодировки Base64 64
64 означает 64 символа.
Сравнительная таблица Base64, заимствованнаяПринцип Base64Картина:
-
A-Z
26 -
a-z
26 -
0-9
10 -
+ /
2
26 + 26 + 10 + 2
= 64
Конечно есть еще один персонаж=
, который является заполняющим символом, о котором будет сказано позже, не относится к категории 64.
сравнительной таблицызначение индекса, Обратите внимание, что кодирование и декодирование base64 будут использоваться позже.
Преимущества и недостатки кодировки Base64
преимущество
- Может преобразовывать двоичные данные (например, изображения) в печатные символы для облегчения передачи данных.
- Простое шифрование данных, безопасное для невооруженного глаза
- Если вы обрабатываете изображения в html или css, вы можете уменьшить количество http-запросов.
недостаток
- После кодирования контента объем становится больше, минимум на 1/3
Поскольку три байта становятся четырьмя байтами, когда есть только один байт, он станет как минимум три байта. - Кодирование и декодирование требуют дополнительной работы
Поговорив о преимуществах и недостатках, вернемся к теме:
Сегодня мы сосредоточимся на преобразовании кодировки uf8 в кодировку Base64:
Основной процесс
char => кодовая точка => кодировка utf-8 => кодировка base64
Прежде чем нам нужно понять знание кодирования, чтобы понять знание кодирования, мы должны сначала понять некоторые базовые знания о компьютерах.
Некоторые основы работы с компьютером и внешним интерфейсом
биты и байты
бит ака бит.
В компьютерном мире представление информации — это только 0 и 1, которые могут представлять два состояния.
Один бит двоичного кода может представлять два состояния, а N битов могут представлять2^N
состояние.
байт(Byte)
имеет 8 бит(Bit)
Таким образом, байт может представлять2^8
= 256 состояний;
Получить кодовую точку Unicode символа
String.prototype.charCodeAtМожно получить кодовую точку символа, а диапазон0
~ 65535
. Обратите внимание на это место, оно связано с количеством байтов utf-8 позади.
"a".charCodeAt(0) // 97
"中".charCodeAt(0) // 20013
базовое представление
-
0b
в начале может представлять двоичный
Уведомление0b10000000
= 128 ,0b11000000
=92, который будет использоваться позже.
0b11111111 // 255
0b10000000 // 128 后面会用到
0b11000000 // 192 后面会用到
-
0x
Вначале он может представлять шестнадцатеричный
0x11111111 // 286331153
0o
Начало может быть выражено восьмеричным, так что больше говорить не буду, оно не будет задействовано в первую очередь.
базовое преобразование
Десятичная система с другими основаниями
Number.prototype.toString(radix)Вы можете конвертировать десятичные числа в другие базы.
100..toString(2) // 1100100
100..toString(16) // 64, 也等于 ox64
Преобразование других оснований в десятичные
parseInt(string, radix)Вы можете преобразовать другие основания в десятичные.
parseInt("10000000", 2) // 128
parseInt("10",16) // 16
Вот дополнительное упоминание символа унарного оператора+
Вы можете преобразовать строки в числа, которые будут использоваться позже, как упоминалось ранее.0b
,0o
,0x
Это будет работать здесь.
+"1000" // 1000
+"0b10000000" // 128
+"0o10" // 8
+"0x10" // 16
операция вытеснения
В этой статье рассматриваются толькопереместить вправоОперация, просто сдвиг вправо, сдвиг вправо эквивалентна делению на 2, если это целое число,Проще говоря, иди вниз, переместите несколько цифр, чтобы удалить несколько цифр, что на самом деле то же самое, что деление на 10 в десятичном виде.
64 >> 2 = 16
Давайте посмотрим на процесс
0 1 0 0 0 0 0 0 64
-------------------
0 1 0 0 0 0 | 0 0 16
Один юань&
операции и унарные|
действовать
Один юань&
Когда оба равны 1, значение равно 1.Роль этой статьи можно использовать, чтобы подняться выше, подробности см. в коде.
3553 & 36
= 0b110111100001 & 0b111111
= 100001
Поскольку старшие биты отсутствуют, они не могут быть все равны 1, поэтому все они равны 0, иНизкий эквивалент, чтобы скопировать его снова.
110111 100001
111111
------------
000000 100001
один доллар |
Когда любой из них равен 1, выход равен 1.Этот лист используется для заполнения0
.
Например, дополнение 3 к 8-битному двоичному коду
3 | 256
= 11 | 100000000
= 100000011
100000011.substring(1)
Это то же самое, что и 8-битный двоичный код?00000011
Обладая этими базовыми знаниями, мы начинаем понимать знания, связанные с кодированием.
ASCII, Юникод, UTF-8
ASCII-код
Первая цифра кода ASCII всегда равна 0, тогда фактическое состояние, которое может быть представлено, равно2^7
= 128 состояний.
ASCII в основном используется для отображениясовременный английский, пока только определил128Символ, содержащий управляющие символы и отображаемые символы.
- от 0 до 31ASCII-кодЧасто используется для управления периферийными устройствами, такими как принтеры.
- от 32 до 127ASCII-кодозначаемый,Можно найти на нашей клавиатуре
Полную таблицу соответствия кодов ASCII см.Базовый ASCII и расширенный ASCII
Далее идет кодировка Unicode и UTF-8, сначала запомните это важное знание:
- Unicode: набор символов
- UTF-8: правила кодирования
Unicode
Unicode присваивает уникальный номер всем символам в мире (кодовая точка), этот номер находится в диапазоне от 0x000000 до 0x10FFFF (шестнадцатеричный), их более 1 миллиона, каждый символ имеет уникальный номер Unicode, этот номер обычно записывается в шестнадцатеричном формате, а U+ добавляется впереди. Например:掘
Юникод U+6398.
- от U+0000 до U+FFFF
Первые 65536 битов символов, диапазон кодовых точек от 0 до216-1. Здесь размещены все самые распространенные символы.
- от U+010000 до U+10FFFF
Здесь размещаются остальные символы с кодовыми точками от U+010000 до U+10FFFF.
В Unicode есть понятие плоскости, поэтому здесь оно не будет раскрываться.
Unicode указывает только кодовую точку для каждого символа, какой порядок байтов используется для представления этой кодовой точки, это связано с методом кодирования.
UTF-8
UTF-8 — наиболее часто используемая реализация Unicode в Интернете. Существуют также такие реализации, как UTF-16 (символы представлены двумя или четырьмя байтами) и UTF-32 (символы представлены четырьмя байтами).
UTF-8 — это метод кодирования переменной длины, количество используемых байтов — отот 1 до 4, последний должен быть больше 4. Этот диапазон от 1 до 4 является ключом к последующему кодированию и декодированию.
Правила кодировки UTF-8:
- Для символов только с одним байтом первый бит байта устанавливается равным
0
, последние 7 цифр — это Unicode-код этого символа. В это время даДля английских букв кодировка UTF-8 и код ASCII совпадают. - для
n
байтовый символ (n > 1
), перед первым байтомn
биты установлены на1
, первыйn + 1
набор бит0
, первые две цифры следующих байтов всегда устанавливаются равными10
. Остальные неупомянутые двоичные биты — это все коды Unicode этого символа, как показано в следующей таблице:
Диапазон кодовых точек Unicode (шестнадцатеричный) | Десятичный диапазон | Кодировка UTF-8 (двоичная) | количество байтов |
---|---|---|---|
0000 0000 ~ 0000 007F |
0 ~ 127 |
0xxxxxxx |
1 |
0000 0080 ~ 0000 07FF |
128 ~ 2047 |
110xxxxx 10xxxxxx |
2 |
0000 0800 ~ 0000 FFFF |
2048 ~ 65535 |
1110xxxx 10xxxxxx 10xxxxxx |
3 |
0001 0000 ~ 0010 FFFF |
65536 ~ 1114111 |
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
4 |
Возможно, мы не видели количество байтов2
или для4
характер,
байты2
можешь идтиТаблица соответствий UnicodeНайти здесь и равно4
ты можешь пойти сюдаUnicode® 13.0 Versioned Charts Index
Следующие кодовые точки находятся в0000 0080 ~ 0000 07FF
, кодировка utf-8 требует 2 байта
Следующие кодовые точки находятся в0001 0000 ~ 0010 FFFF
, кодировка utf-8 требует 4 байта
Может быть, это сложно понять, просто говоря об этом здесь, мы используем английские символы соответственно.a
и китайские иероглисты掘
Объяснить:
Чтобы проверить результаты, вы можете перейти кConvert UTF8 to Binary Bits - Online UTF8 Tools
английские символыa
- Сначала получите его кодовую точку,
"a".charCodeAt(0)
равный97
- Сравнительная таблица, 0~127, обязательна
1
байты -
97..toString(2)
получить кодировку1100001
- Согласно формату
0xxxxxxx
заливка, конечный результат
01100001
Китайские символы掘
- Сначала получите его кодовую точку,
"掘".charCodeAt(0)
равный25496
- Справочная форма, 2048 ~ 65535 обязательна
3
байты -
25496..toString(2)
закодироваться110 001110 011000
- Корневой формат
1110xxxx 10xxxxxx 10xxxxxx
Заполните, окончательный результат выглядит следующим образом
11100110 10001110 10011000
Convert UTF8 to Binary Bits - Online UTF8 ToolsРезультат выполнения: точное совпадение
Абстрактный метод преобразования символов в двоичный формат utf8
Основываясь на приведенной выше таблице и процессе преобразования, мы абстрагируем метод, который находится вПосле этого кодирование и декодирование Base64 имеет решающее значение.:
Сначала посмотрите на функцию, охватывающую диапазон 1-3 байта кодировки utf8.
console.log(to_binary("A")) // 11100001
console.log(to_binary("س")) // 1101100010110011
console.log(to_binary("掘")) // 111001101000111010011000
Методы, как показано ниже
function to_binary(str) {
const string = str.replace(/\r\n/g, "\n");
let result = "";
let code;
for (var n = 0; n < string.length; n++) {
//获取麻点
code = str.charCodeAt(n);
if (code < 0x007F) { // 1个字节
// 0000 0000 ~ 0000 007F 0 ~ 127 1个字节
// (code | 0b100000000).toString(2).slice(1)
result += (code).toString(2).padStart(8, '0');
} else if ((code > 0x0080) && (code < 0x07FF)) {
// 0000 0080 ~ 0000 07FF 128 ~ 2047 2个字节
// 0x0080 的二进制为 10000000 ,8位,所以大于0x0080的,至少有8位
// 格式 110xxxxx 10xxxxxx
// 高位 110xxxxx
result += ((code >> 6) | 0b11000000).toString(2);
// 低位 10xxxxxx
result += ((code & 0b111111) | 0b10000000).toString(2);
} else if (code > 0x0800 && code < 0xFFFF) {
// 0000 0800 ~ 0000 FFFF 2048 ~ 65535 3个字节
// 0x0800的二进制为 1000 00000000,12位,所以大于0x0800的,至少有12位
// 格式 1110xxxx 10xxxxxx 10xxxxxx
// 最高位 1110xxxx
result += ((code >> 12) | 0b11100000).toString(2);
// 第二位 10xxxxxx
result += (((code >> 6) & 0b111111) | 0b10000000).toString(2);
// 第三位 10xxxxxx
result += ((code & 0b111111) | 0b10000000).toString(2);
} else {
// 0001 0000 ~ 0010 FFFF 65536 ~ 1114111 4个字节
// https://www.unicode.org/charts/PDF/Unicode-13.0/U130-2F800.pdf
throw new TypeError("暂不支持码点大于65535的字符")
}
}
return result;
}
В методе есть три места, которые немного сложно понять, давайте интерпретируем их вместе:
- двухбайтовый
(code >> 6) | 0b11000000
Его роль заключается в генерации двоичного кода высокого порядка.
Мы объясняем с настоящим каштаном, сس
Например, его кодовая точка0x633
,существует0000 0080 ~ 0000 07FF
между , занимая два байта, а его двоичный код11 000110011
, формат заполнения следующий, следует использовать младший разряд6 бит.
110xxxxx 10xxxxxx
Для удобства наблюдения положим11 000110011
приспособиться11000 110011
.
(код >> 6) равен 00110011 >> 6, сдвиг вправо на 6 бит и прямое уничтожение младших 6 бит. Почему 6, потому что для младшего разряда требуется 6 бит.После перемещения 6 бит вправо, остальные биты используются для операции старшего разряда.
11000000
11000 | 110011
--------------
11011000
-
двухбайтовый
(code & 0b111111) | 0b10000000
Роль, используемая для генерации младшего двоичного файла. кس
Например,11000 110011
, формат заполнения
110xxxxx 10xxxxxx
(code & 0b111111)这步的操作是为了干掉6位以上的高位,仅仅保留低6位
. Один юань&
Символ, когда обе стороны равны 1, будет 1, замечательно.
11000 110011
111111
------------------
110011
затем продолжайте| 0b10000000
, в основном в соответствии с форматом10xxxxxx
Заполнение выполняется, чтобы заполнить его 8 битами.
11000 110011
111111 (code & 0b111111)
------------------
110011
10 000000 (code & 0b111111) | 0b10000000
-------------------
10 110011
Кодирование и декодирование Base64
правила кодирования utf-8 в Base64
- Получить код Unicode для каждого символа, перейти на кодировку UTF-8
-
три байтаВ группе всего 24 двоичных бита
Количество байтов не делится на 3, дополненное в конце 0-байтовым значением - согласно с6 битГруппа групп, первые два бита заполнены 0, а 8 бит собраны
- Рассчитать стоимость каждого пакета
- с первым
4
Значение шага используется в качестве индекса, и перейдите к таблице кодов ASCII, чтобы найти соответствующее значение. - заменить первый
2
шагДобавьте количество байтовиз=
например первый2
Добавил 2 байта, за ним 2=
слишком большой掘A
Например, мы передаем вышеutf8_to_binary
способ получить кодировку utf8
11100110 10001110 10011000 11000001
, количество байт не делится на 3 и заполняется позже
11100110
10001110
10011000
01000001
--------
00000000
00000000
6-битная группа делится на четыре группы, старшее дополнение0
, использовать|
Разделить и заполнить.
00 | 111001 => 57 => 5
00 | 101000 => 40 => o
00 | 111010 => 58 => 6
00 | 011000 => 24 => Y
00 | 110000 => 16 => Q
00 | 010000 => 16 => Q
00 | 000000 => => =
00 | 000000 => => =
оказаться:5o6YQQ==
, Идеально.
Реализация кода правила кодирования utf-8 в Base64
На основании вышеизложенногоto_binary
Метод и правила преобразования base64 очень просты:
Давайте посмотрим на эффект реализации, очень хороший, иbase64.usРезультаты точно такие же.
console.log(utf8_to_base64("a")); // YQ==
console.log(utf8_to_base64("Ȃ")); // yII=
console.log(utf8_to_base64("中国人")); // 5Lit5Zu95Lq6
console.log(utf8_to_base64("Coding Writing 好文召集令|后端、大前端双赛道投稿,2万元奖池等你挑战!"));
//Q29kaW5nIFdyaXRpbmcg5aW95paH5Y+s6ZuG5Luk772c5ZCO56uv44CB5aSn5YmN56uv5Y+M6LWb6YGT5oqV56i/77yMMuS4h+WFg+WlluaxoOetieS9oOaMkeaImO+8gQ==
Полный код выглядит следующим образом:
const BASE64_CHARTS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
function utf8_to_base64(str: string) {
let binaryStr = to_binary(str);
const len = binaryStr.length;
// 需要填补的=的数量
let paddingCharLen = len % 24 !== 0 ? (24 - len % 24) / 8 : 0;
//6个一组
const groups = [];
for (let i = 0; i < binaryStr.length; i += 6) {
let g = binaryStr.slice(i, i + 6);
if (g.length < 6) {
g = g.padEnd(6, "0");
}
groups.push(g);
}
// 求值
let base64Str = groups.reduce((b64str, cur) => {
b64str += BASE64_CHARTS[+`0b${cur}`]
return b64str
}, "");
// 填充=
if (paddingCharLen > 0) {
base64Str += paddingCharLen > 1 ? "==" : "=";
}
return base64Str;
}
Что же касается расшифровки, то это обратный процесс, и я предоставляю каждому понять его.
Другие зрелые решения
- Конечно, на основе существующих
btoa
а такжеatob
,
Но unescape - устаревший метод
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
function b64_to_utf8( str ) {
return decodeURIComponent(escape(window.atob( str )));
}
// Применение: utf8_to_b64('✓ в режиме'); // "4pyTIMOgIGxhIG1vZGU=" b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ в режиме"
Он поддерживает до 6 байт, но читабельность не очень хорошая.
- сторонняя библиотекаbase64-jsа такжеjs-base64Все они представляют собой библиотеки с более чем миллионом загрузок в неделю.
Хотя существует так много зрелых, мы можем лучше понять принцип кодирования Base64, если поймем и реализуем его сами.
добавить немного больше
- схема кодирования
занимать[Вы действительно знаете Unicode и UTF-8?] Картинка:
-
DOMStringда
utf-16
кодирование
напиши в конце
Писать нелегко, ваши три подряд (один лайк, один комментарий, один лайк) — моя самая большая мотивация.
подобноболее ста, а затем писать статьи о программировании, таком как браузеры, DOM, JS и т. д.
Цитировать
Version-Specific Charts
Unicode13.0.0
Unicode® 13.0 Versioned Charts Index
RFC 4648 | The Base16, Base32, and Base64 Data Encodings
Base64 encoding and decoding
Примечания по кодировке символов: ASCII, Unicode и UTF-8
Подробный Unicode и JavaScript
Начало работы с кодировкой Base64 Принцип Base64
Подробно объясните принцип base64.
Одна статья для понимания кодировки base64
Кое-что о base64 в JS
Принцип, реализация и применение Base64
Отношения преобразования изображения и Base64
[Вы действительно знаете Unicode и UTF-8?]
Подробное объяснение кодировки UTF-8 и UTF-16 в Unicode.
Таблица соответствий Unicode
Подробная карта исходного кода JavaScript