Js base64编码实现

Js base64编码实现

base64在前端领域中是相当有用,比如前端里的dataURL就是base64编码实现的,使用它的好处就很多了,假如需要从服务器拿到一些logo,但是这些logo可能只有几十byte甚至更小,那这样这个logo单独占用一条http传输是很不划算的,我们可以把这个logo进行base64编码,也就是dataURL,直接嵌入页面中,在浏览器获取页面的时候,直接由浏览器渲染出来,但是要知道base64编码出来的体积要比原来大,如果要把一个比较大的突破编码成dataURL,那是相当庞大的,显然不适合直接嵌入页面中,这样会使页面加载过于缓慢。最后要说到base64的浏览器支持问题,除了ie8以下的版本不能很好的支持之外,其他的浏览器大都支持(未测试)。

纸上得来终觉浅,绝知此事要躬行

既然base64编码这么有用,不妨来了解一下base64的原理。
· base64的编码都是按字符串长度,以每3个8bit的字符为一组
· 首先把每组的字符都转换为ascii码
· 然后把ascii码转换为8位二进制数
· 现在得到了24位二进制数,把它分为4个6位二进制数,并在最高位补两个0
· 再分后的四个二进制数转换为十进制
· 然后对比base64编码表,来进行转换

Base64 编码表
Value Char Value Char Value Char
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

比如我们举个例子,我们现在要将“haa”转换为base64编码
首先转换为ascii码为 104, 97, 97
再转换为8位二进制为 0110 1000, 0110 0001, 0110 0001
分为4组为,0001 1010, 0000 0110, 0000 0101,0010 0001
现在把它们都转换为10进制为:26,6,5,33
对照base64编码表为:aGFh

这是刚好可以分为三个一组的字符串,但是如果不是3的倍数呢
比如现在有个例子,我们需要将”hello”转换为base64编码
现在三个分为一组,就是”hel”,”lo”
还是先转换为ascii码 : 104, 101,108,108,111
再转换为二进制的时候需要用0补齐:0110 1000, 0110 0101, 0110 1100, 0110 1100, 0110 1111,0000 0000
把他们分为八组为:0001 1010,0000 0110,0001 0101,0010 1100,0001 1011,0000 0110,0011 1100,00 0000
现在将它们转为10进制,这里需要注意的是由于后面的0是我们补全的,因此这里转换为base64编码的时候就不能对照base64编码,而是变为“=”:26,6,21,44,27,6,60,异常
对照base64编码表为:aGVsbG8=

现在原理大家都大概高清楚了,那我们自己用js实现一个base64的编码器吧!

/**
 * @description base64编码方法
 * @param val 需要编码的字符串
 * @return 返回编码好的base64字符串
 */
function encodingBase64(val){
    let base64hash = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

    //把字符串转换为字符数组
    let strArr = val.split('')

    //装入结果的数组
    let result = []
    //每个字符的ascii码
    let asciiCode
    //上一个字符的ascii码
    let prevAsciiCode

    let mod
    //未填充之前的数组与3的模
    let preMod = strArr.length % 3

    //使字符数组组成三个一组
    if(preMod == 1){
        strArr.push(null)
        strArr.push(null)
    }
    if(preMod == 2) strArr.push(null)
    //遍历整个数组,寻找每个字符的ascii码
    for(let index in strArr){
        if(!strArr[index]){
            asciiCode = 0
        }
        else{
            asciiCode = strArr[index].charCodeAt()
        }
        //位于一组当中的第几个字符
        mod = index % 3
        switch(mod){
            case 0:
                //往右移2位
                result.push(base64hash[asciiCode >> 2])
                break
            case 1:
                //上一个ascii码往左移4位与现在的ascii码往右移四位做或操作
                result.push(base64hash[(prevAsciiCode & 3) << 4 | asciiCode >> 4])
                break
            case 2:
                result.push(base64hash[(prevAsciiCode & 15) << 2 | asciiCode >> 6])
                result.push(base64hash[asciiCode & 63])
                break
        }

        prevAsciiCode = asciiCode
    }

    //处理异常
    if(preMod == 1) {
        result.splice(result.length - 2,2)
        result.push('==')
    }
    else if(preMod == 2) {
        result.pop()
        result.push('=')
    }

    return result.join('')
}

下面我们试一下这个函数

console.log(encodingBase64("hello")) //aGVsbG8=

可以看到已经成功的进行base64编码了!!

你可能感兴趣的:(javascript,Javascript,!!!)