1. Происхождение кодировки Base64
Почему существует кодировка Base64? Поскольку некоторые сетевые каналы передачи не поддерживают все байты, например, традиционная почта поддерживает передачу только видимых символов, таких как ASCII.управляющие символынельзя отправить по почте. Таким образом, использование сильно ограничено, например, каждый байт двоичного потока изображения не может состоять из всех видимых символов, поэтому его нельзя передать. Лучший способ — создать схему расширения для поддержки передачи двоичных файлов без изменения традиционного протокола. Представление непечатаемых символов печатными символами решает проблему. Появилась кодировка Base64, Base64 — это метод представления, основанный на 64 печатных символах для представления двоичных данных.
2. Принцип кодирования Base64
Большинство наших изображений представляют собой данные: изображения, которые можно преобразовать в кодировку base64. Это особенно полезно при сохранении холста как img. Современные браузеры уже поддерживают собственное кодирование и декодирование на основе base64, напримерbtoaа такжеatob
Глядя на таблицу индексов Base64, символы «AZ, az, 0-9, +, /» 64 печатных символа. Значение представляет собой индекс символа, который определяется стандартным протоколом Base64 и не может быть изменен. 64 символа могут быть представлены битами 6. Один байт имеет 8 бит, а оставшиеся два бита тратятся впустую, поэтому приходится жертвовать некоторым пространством. Здесь нужно понимать, что символ Base64 — это 8 бит, но действительная часть — это только 6 бит справа, а два слева всегда равны 0.
Итак, как использовать 6 допустимых битов для представления 8 битов традиционных символов? Наименьшее общее кратное 8 и 6 равно 24, что означает, что 3 традиционных байта могут быть представлены 4 символами Base64, гарантируя, что количество значащих цифр будет одинаковым, поэтому есть дополнительная 1/3 количества байтов для восполнить недостаток Base64 только в 6 действительных битах. Вы также можете сказать, что два символа Base64 также могут представлять традиционный символ, но схема использования наименьшего общего кратного на самом деле наименее расточительна. Это легче понять с диаграммой ниже. Man состоит из трех символов, всего 24 допустимых бита, поэтому мы должны использовать 4 символа Base64, чтобы составить 24 допустимых бита. Красное поле представляет соответствующий Base64, а 6 допустимых битов преобразуются в соответствующее значение индекса, а затем в соответствие с таблицей символов Base64.Обнаружено, что символ Base64, соответствующий «Человеку», представляет собой «TWFU». Кстати тут есть принцип, не знаю нашел ли ты его, его нужно конвертировать в Base64Наименьшая единица — три байта., для строки это преобразование трех байтов и трех байтов каждый раз, что соответствует четырем байтам Base64. Это почти ясно.
Но что, если вы обнаружите, что в конце конвертации не хватает трех байтов? Желание, наконец, сбылось. Мы можем использовать два Base64 для представления одного символа или три Base64 для представления двух символов. Как показано на рисунке ниже, второй Base64, соответствующий A, имеет только два двоичных бита, а четыре обратно заполнить 0 , Вот и все. Таким образом, символ Base64, соответствующий A, — это QQ. Как упоминалось выше, принцип заключается в использовании символов Base64.Наименьшая единица — это группа из четырех символов., то это всего два символа, поэтому добавьте два "=" после него. Фактически, нет необходимости в "=", и декодирование не задерживается. Причина, по которой используется "=", может заключаться в том, что это не вызовет путаницы при написании нескольких закодированных строк Base64. Видно, что строка Base64 может иметь только один или два «=» в конце, а «=» в середине быть не может. Процесс кодирования символа «BC» на рисунке ниже такой же.
3. Конкретная реализация:
Давайте посмотрим, как использовать транскодирование Base64 в javascript.
var str = 'javascript';
window.btoa(str)
//转码结果 "amF2YXNjcmlwdA=="
window.atob("amF2YXNjcmlwdA==")
//解码结果 "javascript"
2. Для транскодирования объектом транскодирования Base64 могут быть только строки, поэтому для остальных данных существуют определенные ограничения, особое внимание следует уделить транскодированию Unicode.
var str = "China,中国"
window.btoa(str)
Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
Очевидно, что этот метод не работает, поэтому как заставить его поддерживать китайские символы, это использовать window.encodeURIComponent и window.decodeURIComponent.
var str = "China,中国";
window.btoa(window.encodeURIComponent(str))
//"Q2hpbmElRUYlQkMlOEMlRTQlQjglQUQlRTUlOUIlQkQ="
window.decodeURIComponent(window.atob('Q2hpbmElRUYlQkMlOEMlRTQlQjglQUQlRTUlOUIlQkQ='))
//"China,中国"
function Base64() {
// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
3. Резюме
Говорить о кодировке Base64 может быть немного странно, потому что большинство кодировок представляет собой процесс преобразования символов в двоичные, а процесс преобразования из двоичных в символы называется декодированием. Концепция Base64 как раз противоположна, от двоичного к символьному называется кодированием, а от символьного к двоичному называется декодированием.
Кодирование Base64 в основном используется в областях передачи, хранения, двоичного представления и т. д. Его также можно использовать для шифрования, но этот вид шифрования относительно прост, он просто не знает, что такое содержимое на первый взгляд, Конечно, последовательность символов Base64 также может быть настроена для шифрования.
Кодирование Base64 — это процесс преобразования двоичного кода в символ.Например, когда некоторые китайские иероглифы преобразуются в двоичные с разными кодировками, результирующий двоичный код отличается, поэтому окончательные символы Base64 также отличаются. Например, кодировка Base64, соответствующая формату utf-8 для «Интернет», — «5LiK572R», а кодировка Base64, соответствующая формату GB2312, — «yc/N+A==".