在青训营刷题中遇到一道base64的问题,发现自己对这部分知识点很不熟悉,以及遗忘了很多,就上网补补课以及将自己的思考和代码记录下来,若有错误路过的大神们帮忙指点一下感谢! 1、首先也先了解其他字符集
- ASCII码,值是十进制的放在计算机中存储要变成二进制
(1)一个ascii码占一个字节同字符大小相同
(1)ascii码第一个数为0,后面7个数来表示字符
(2)只有128个编码
- unicode,值是十六进制的
(1)什么是编码规则? 编码规则规定了unicode值要怎么转换成二进制存储在计算机中,比如utf-8(一种变长编码),将一个字符进行编码的时候,除了英文字符是完全兼容ascii码最前面的二进制是0之外,其余的编码会在前面加上这个编码的字节大小,比如中文“中”占三个字节会在最前面加上3个1
注意!编码和解码要用同一个编码规则,否则会乱码
(2)unicode与ascii码
unicode前128位与ascii码完全相同
2、了解base64原理
首先将所有的字符转成二进制然后每6个bit截取一次编码
注意:一个char字符是1个字节也就是8个bit
知识点回顾:
1、获取字符的ascii码(十进制)
str.charCodeAt()
2、将unicode码点或者ascii码值转成字符
String.fromCodePoint(码点)//码点可以是十进制也可以是十六进制,但是注意十进制使用toString(16)转成的十六进制需要在前面补上0x
2、转成二进制
str.charCodeAt().toString(2)
3、将字符串用指定字符补成指定位数的字符串
str.padStart(8,'0')//将字符串前面补0补成8位的字符串
4、如何获得大写和小写的26个字符的字符串
(1)首先要知道大写A的码点是65,小写a的码点是97
(2)获得大写字符的字符串
let str1 = new Array(26).fill(65).map((ele,index)=>{
return String.fromCodePoint(ele+index)
}).join('')
(3)获得小写字符的字符串
let str2 = new Array(26).fill(97).map((ele,index)=>{
return String.fromCodePoint(ele+index)
}).join('')
5、将数字字符转成十进制数字,并且指明源数字进制
let num = parseInt('0101',2)
代码实现:
function toBase64(str){
//1、查找ASCII码表,将字符转成二进制数
const code = str.split('').reduce((prev,cur)=>{
return prev+cur.charCodeAt().toString(2).padStart(8,'0')//用padStart函数补成8位bit
},'')//注意reduce只能用于数组不能用于字符串
//2、因为一个字符占8个比特而base64需要的是6个比特表示一个字符,难免会有空的情况需要补0,补了几个00就要加上几个=
let res = ''
if(code.length%6==2){
code+='00'
res ='='
}
else if(code.length%6==4){
code+='0000'
res = '=='
}
//3、将每6位二进制数划分为一组,一组表示一个字符,6个二进制数能表示64位字符(大小写英文字母+/)
let encode = ''
const str1 = new Array(26).fill(65).map((ele,index)=>{
return String.fromCodePoint(ele+index)
}).join('')//26位大写字母组成的字符串
const str2 = new Array(26).fill(97).map((ele,index)=>{
return String.fromCodePoint(ele+index)
}).join('')
const base64Str = str1+str2+'0123456789+/'
for(let i=0;i<code.length;i+=6){
let item = code.slice(i,i+6)//6个进制为一组
encode+=base64Str[parseInt(item,2)]
}
return encode+res
}