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