Let’s start with common usage scenarios
-
1. Reduce HTTP requests and encode images as SRC values
<img alt="Embedded Image" src="data:image/png; base64,iVBORw0KGgoAFFFASDWQQWQWIA..." /> Copy the code
-
2, not easy to read, some plaintext data encoding
window.btoa('mypassword') // "bXlwYXNzd29yZA==" Copy the code
-
3. Export the canvas to generate a picture download
let url = canvas.toDataUrl() // Return a base64 string let a = document.createElement('a') a.setAttribute('download'.'canvas.png') a.href = url a.style.display = 'none' document.body.appendChild(a) a.click() Copy the code
Browser Window built-in methods
Window.btoa (Binary to Ascii)
I can’t remember who was first in this API, but after checking the full name, I have a little impression.
/ / code
window.btoa('mypassword')
// "bXlwYXNzd29yZA=="
Copy the code
Atob (Ascii to Binary)
/ / decoding
window.atob('bXlwYXNzd29yZA==')
// "mypassword"
Copy the code
So, what is it, and why is a string displayed as a picture?
First of all, we all know that high-level languages like Java and javascript, translated by high-level languages — > assembly language — > machine language, are really just a bunch of binary data.
So an image is essentially just a bunch of data all the time, but sensory misunderstandings.
When our Windows. Btoa (‘ Hello!!!!! ‘) when encoding
- 1, first check whether the encoded string is in Ascii code, if so, otherwise error
- 2. Convert string by string to Ascii code
The original character | H | e | l | l | o | ! | ! |
---|---|---|---|---|---|---|---|
Ascii | 72 | 101 | 108 | 108 | 111 | 33 | 33 |
For example, Hello becomes ASCII 72, 101, 108, 108, 111
- 3. Convert ASCII to binary
The original character | H | e | l | l | o | ! | ! |
---|---|---|---|---|---|---|---|
Ascii | 72 | 101 | 108 | 108 | 111 | 33 | 33 |
binary | 0100, 1000, | 0110, 0101, | 0110, 1100, | 0110, 1100, | 0110, 1111, | 0010, 0001, | 0010, 0001, |
- Key 4, the third step of the binary string in order to take 6 segmentation
// Original binary:
// 0100 1000 0110 0101 0110 1100 0110 1100 0110 1111 0010 0001 0010 0001
// Divide by 6:
// 010010 000110 010101 101100 011011 000110 111100 100001 001000 010000 000000 000000
Copy the code
You might notice that after splitting, the binary string gets longer. This is because there will be a remainder when the binary string length is truncated by 6. At this time, zero fill will be carried out until the binary string length meets the requirement that the remainder of 6 and 8 is equal to 0.
Here’s a picture that’s a little bit clearer
The original link is: www.cnblogs.com/peterYong/p…
-
5, after the previous steps to get the new binary string, and then restore the binary string to Ascii code
-
6. Map the resulting Ascii code into the Base64 table
-
7. Specify the end of base64
Because of the possibility of zero-filling in the fourth step, the standard usually agrees to replace the ending A with =, indicating the end of the original character. This is why we often see = in a base64 string.
Javascript version of the encoding implementation
// Initialize the Base64 mapping table
function initBase64Map() {
let map = {};
for (let i = 0; i < 26; i++) {
map[i] = String.fromCharCode(65 + i);
map[26 + i] = String.fromCharCode(97 + i);
if (i < 10) {
map[52 + i] = i;
}
}
map[62] = "+";
map[63] = "/";
return map;
}
const base64Map = initBase64Map()
class Data {
constructor() {}
// Check whether single-byte data is available
static isValid(str) {
for (let i = 0; i < str.length; i++) {
const cur = str[i];
if (cur.charCodeAt() > 126) {
return false; }}return true;
}
// Perform zeroing
static _convertToBinary(asciiCode) {
// Convert decimal to binary, then fill zero
let code = parseInt(asciiCode).toString(2);
while (code.length < 8) {
code = "0" + code;
}
return code;
}
static convertToBinaryData(strData) {
let result = "";
this._formatBinary = "";
for (let i = 0; i < strData.length; i++) {
const str = strData[i];
const asciiCode = str.charCodeAt();
const binaryCode = Data._convertToBinary(asciiCode);
result += binaryCode;
this._formatBinary += binaryCode + "";
}
return result;
}
// Since the original 8-byte data is split into 6 bytes, less than 8 bytes and 6 bytes of binary, need to add zero at the end
static fillZero(binary) {
while (binary.length % 6! = =0 || binary.length % 8! = =0) {
binary = binary + "0";
}
return binary;
}
static toBase64(binaryCode) {
let result = "";
for (let i = 0; i < binaryCode.length; i += 6) {
const binary = binaryCode.substring(i, i + 6);
result += base64Map[parseInt(binary, 2)];
}
let arr = result.split("");
for (let i = arr.length - 1; i > 0; i--) {
if (arr[i] === "A") {
arr[i] = "=";
} else {
break; }}return arr.join("");
}
static encode(str) {
if (!this.isValid(str)) {
return new Error("String contains characters not in ASCII range");
}
let binaryCodeOrigin = Data.convertToBinaryData(str);
let fillZeroBinaryCode = Data.fillZero(binaryCodeOrigin);
let result = Data.toBase64(fillZeroBinaryCode);
returnresult; }}window.btoa('Hello!!! ') === Data.encode('Hello!!! ')
Copy the code
related
Do you know why window.btoa(‘ Chinese ‘) gives an error?
What is Ascii code
Is a set of character codes based on the Latin alphabet, a total of 128 characters, with a byte can be stored
Ascii code comparison table
Ascii code comparison table
The last
Hulanzao, only clear the general coding ideas, there is wrong, not rigorous place please point out