Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 144 题:手写二进制转 Base64 #299

Open
igoryaodev opened this issue Oct 20, 2019 · 14 comments
Open

第 144 题:手写二进制转 Base64 #299

igoryaodev opened this issue Oct 20, 2019 · 14 comments

Comments

@igoryaodev
Copy link

base64编码

@igoryaodev igoryaodev changed the title 第 144题:二进制转base64 第 144题:二进制转base64(阿里) Oct 20, 2019
@igoryaodev igoryaodev changed the title 第 144题:二进制转base64(阿里) 第 144题:手写二进制转base64(阿里) Oct 20, 2019
@yygmind yygmind changed the title 第 144题:手写二进制转base64(阿里) 第 144 题:手写二进制转 Base64 Oct 22, 2019
@yygmind yygmind added the 阿里 label Oct 22, 2019
@zhenbushidashen
Copy link

let  binaryDataToBase64 = byte => {
     let sBytes =  new Uint8Array(byte).reduce((accu,next)=> {
         retrun accu + String.fromCharCode(next)
}, '')
    return `data:image/png;base64,${btoa(sBytes)}` 
}

@Pazzilivo
Copy link

String.fromCharCode(...new Uint8Array(response.data))

https://blackstar.coding.me/2018-08-23-arraybuffer-to-base64orblob.html

@chenxiaoleizi
Copy link

String.fromCharCode(...new Uint8Array(response.data))

https://blackstar.coding.me/2018-08-23-arraybuffer-to-base64orblob.html
使用Uint8Array的时候怎么确定分配的内存是够用啊,Uint8Array应该只能分配8位(一个字节)的内存吧

@muzishuiji
Copy link

btoa

bota是一个工具函数吗

@fengqinglingyu
Copy link

node 端:
toBase64:

Buffer.from('123').toString('base64')

decode:

Buffer.from('MTIz', 'base64').toString()

浏览器端:
toBase64

btoa('123')

decode

atob('MTIz')

btoa 和 atob 都是 window 上的方法,atob 全称 ascii to binary ,反之亦然

@sisterAn
Copy link
Collaborator

sisterAn commented Nov 6, 2019

字符转二进制

function charToBinary(text) {
  var code = "";
  for (let i of text) {
    // 字符编码
    let number = i.charCodeAt().toString(2);
    // 1 bytes = 8bit,将 number 不足8位的0补上
    for (let a = 0; a <= 8 - number.length; a++) {
       number = 0 + number;
    }
    code += number;
  }
  return code;
}

二进制转Base64

// 将二进制数据每 6bit 位替换成一个 base64 字符
function binaryTobase64(code) {
  let base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  let res = '';
  // 1 bytes = 8bit,6bit 位替换成一个 base64 字符
  // 所以每 3 bytes 的数据,能成功替换成 4 个 base64 字符
    
  // 对不足 24 bit (也就是 3 bytes) 的情况进行特殊处理
  if (code.length % 24 === 8) {
    code += '0000';
    res += '=='
  }
  if (code.length % 24 === 16) {
    code += '00';
    res += '='
  }

  let encode = '';
  // code 按 6bit 一组,转换为
  for (let i = 0; i < code.length; i += 6) {
    let item = code.slice(i, i + 6);
    encode += base64Code[parseInt(item, 2)];
  }
  return encode + res;
}

字符转Base64

function base64encode(text) {
  let base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  let res = '';
  let i = 0;
  while (i < text.length) {
    let char1, char2, char3, enc1, enc2, enc3, enc4;
    
    // 三个字符一组,转二进制
    char1 = text.charCodeAt(i++); 
    char2 = text.charCodeAt(i++);
    char3 = text.charCodeAt(i++);

    enc1 = char1 >> 2; // 取第 1 字节的前 6 位
    
    // 三个一组处理
    if (isNaN(char2)) {
      // 只有 1 字节的时候
      enc2 = ((char1 & 3) << 4) | (0 >> 4);
      // 第65个字符用来代替补位的 = 号
      enc3 = enc4 = 64;
    } else if (isNaN(char3)) {
      // 只有 2 字节的时候
      enc2 = ((char1 & 3) << 4) | (char2 >> 4);
      enc3 = ((char2 & 15) << 2) | (0 >> 6);
      enc4 = 64;
    } else {
      enc2 = ((char1 & 3) << 4) | (char2 >> 4); // 取第 1 个字节的后 2 位(3 = 11 << 4 = 110000) + 第 2 个字节的前 4 位
      enc3 = ((char2 & 15) << 2) | (char3 >> 6); // 取第 2 个字节的后 4 位 (15 = 1111 << 2 = 111100) + 第 3 个字节的前 2 位
      enc4 = char3 & 63; // 取最后一个字节的最后 6 位 (63 = 111111)
    }
    
    // 转base64
    res += base64Code.charAt(enc1) + base64Code.charAt(enc2) + base64Code.charAt(enc3) + base64Code.charAt(enc4)
  }

  return res;
}

字符转Base64-最优解(window.btoa,window.atob)✅✅✅

let encodedData = window.btoa("this is a example");
console.log(encodedData); // dGhpcyBpcyBhIGV4YW1wbGU=

let decodeData = window.atob(encodedData);
console.log(decodeData); // this is a example

@irina9215
Copy link

irina9215 commented Nov 19, 2019

function Base64Encode(string) {
    return btoa(encodeURIComponent(string).replace(/%([0-9A-F]{2})/g,
        (match, p1) => String.fromCharCode(`0x${p1}`)));
}

@jichenchen91
Copy link

window 方法 atob btoa

@Jmingzi
Copy link

Jmingzi commented Dec 3, 2019

String.fromCharCode(...new Uint8Array(response.data))

https://blackstar.coding.me/2018-08-23-arraybuffer-to-base64orblob.html
使用Uint8Array的时候怎么确定分配的内存是够用啊,Uint8Array应该只能分配8位(一个字节)的内存吧

Uint8Array 并不表示分配的 ArrayBuffer 的大小,length 才是, 无符号8位整数,表示当前存放的内容的字节大小是单字节字符,即1个字节8位。对于超过 ASCII 128 位的字符就不够用了,除此之外,我们还需要知道 TypedArray 里存放的是什么?是 unicode 码点。

// 例如
var v = new Uint8Array(8)
v[0] = '我'.charCodeAt() // 码点是 25105
console.log(v[0]) // 17 并不是 25105,因为超过了 2^7 = 128 
v[0] = '1'.charCodeAt() // 码点是 49
console.log(v[0]) // 49

unicode 基本平面内的字符是兼容 ASCII 码的,但是超过128位后,是双字节字符,用 Uint16Array 来表示,对于 emoji 表情 4 字节字符,用 Uint32Array 来表示。

https://iming.work/detail/5b80acd70b61600062edc375

@DunDun1124
Copy link

function mybtoa(data) {
    var result = [];
    var bArray = [];
    var baseTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789+/"
    for (let index = 0; index < data.length; index++) {
      bArray.push(data.charCodeAt(index).toString(2))
    }
    bArray = bArray.map(para => {
      while (para.length < 8) {
        para = "0" + para;
      }
      return para;
    })
    var str = bArray.join('');
    var addZero =3- (str.length/8)%3
    var addAscii='';

    for (let index = 0; index < str.length%6; index++) {
      str+='0'
    }
   
    for (let index = 0; index < addZero; index++) {
      addAscii+="=";
    }
    for (let index = 0; index < str.length; index += 6) {
      result.push(baseTable[parseInt(str.substr(index, 6), 2)]);

    }
    return result.join('')+addAscii
  }

@cutie6
Copy link

cutie6 commented Jun 7, 2020

```js
String.fromCharCode(...new Uint8Array(response.data))

https://blackstar.coding.me/2018-08-23-arraybuffer-to-base64orblob.html

这里返回的字符串还需要用 window.btoa() 处理一下才能是 base64 编码的 ASCII 字符串吧

@CHENJIAMIAN
Copy link

CHENJIAMIAN commented Jun 12, 2020

MDN Base64的编码与解码

由于 DOMString 是16位编码的字符串,所以如果有字符超出了8位ASCII编码的字符范围时,在大多数的浏览器中对Unicode字符串调用 window.btoa 将会造成一个 Character Out Of Range 的异常。有很多种方法可以解决这个问题:

第一种方法是将JavaScript的本机UTF-16字符串直接编码为base64(快速,可移植,干净)
第二种方法是将JavaScript的本机UTF-16字符串转换为UTF-8,然后将后者编码为base64(相对快速,可移植,干净)。
第三种方法是通过二进制字符串将JavaScript的本地UTF-16字符串直接编码为base64(非常快,相对可移植,非常紧凑)
第四种方法是转义整个字符串(使用UTF-8,请参见encodeURIComponent),然后对其进行编码(便携式,非标准)
第五种方法类似于第二种方法,但是使用第三方库

@WangXBruc
Copy link

```js
String.fromCharCode(...new Uint8Array(response.data))

https://blackstar.coding.me/2018-08-23-arraybuffer-to-base64orblob.html

This is not a good solution. String.fromCharCode is used to transform utf-16 code to string.

@gitwillsky
Copy link

来个字符串转二进制的函数:

function s2b(s) {
  return s.split('').map(c => c.charCodeAt(0).toString(2).padStart(8, 0)).join('');
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests