zoukankan      html  css  js  c++  java
  • JS的base64编码解码

    Unicode问题解法

    有个小坑是它只支持ASCII. 如果你调用btoa("中文")会报错:

    Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

    浏览器中DOMString是UTF-16编码. 如果输入字符串中包含超过8位(0x00~0xFF)的字符, 就会报这个错误.

    思路一

    对整个字符串进行转义(如使用encodeURIComponent 进行UTF-8转义)然后再btoa编码.

    let Base64 = {
        encode(str) {
            // first we use encodeURIComponent to get percent-encoded UTF-8,
            // then we convert the percent encodings into raw bytes which
            // can be fed into btoa.
            return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
                function toSolidBytes(match, p1) {
                    return String.fromCharCode('0x' + p1);
                }));
        },
        decode(str) {
            // Going backwards: from bytestream, to percent-encoding, to original string.
            return decodeURIComponent(atob(str).split('').map(function (c) {
                return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
            }).join(''));
        }
    };
    
    let encoded = Base64.encode("哈ha"); // "5ZOIaGE="
    let decoded = Base64.decode(encoded); // "哈ha"

    思路二

    将UTF-16的DOMString转化成UTF-8的字节数组然后编码.

    MDN上此思路的解法用了很多库, 就不推荐了.

    网上找到了下面这段代码, 思路是一样的, 但是是直接裸写的转换代码.

    /**
    *
    *  Base64 encode / decode
    *  http://www.webtoolkit.info
    *
    **/
    var Base64 = {
    
        // private property
        _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    
        // public method for encoding
        , encode: function (input)
        {
            var output = "";
            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
            var i = 0;
    
            input = Base64._utf8_encode(input);
    
            while (i < input.length)
            {
                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);
    
                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;
    
                if (isNaN(chr2))
                {
                    enc3 = enc4 = 64;
                }
                else if (isNaN(chr3))
                {
                    enc4 = 64;
                }
    
                output = output +
                    this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                    this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
            } // Whend 
    
            return output;
        } // End Function encode 
    
    
        // public method for decoding
        ,decode: function (input)
        {
            var output = "";
            var chr1, chr2, chr3;
            var enc1, enc2, enc3, enc4;
            var i = 0;
    
            input = input.replace(/[^A-Za-z0-9+/=]/g, "");
            while (i < input.length)
            {
                enc1 = this._keyStr.indexOf(input.charAt(i++));
                enc2 = this._keyStr.indexOf(input.charAt(i++));
                enc3 = this._keyStr.indexOf(input.charAt(i++));
                enc4 = this._keyStr.indexOf(input.charAt(i++));
    
                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;
    
                output = output + String.fromCharCode(chr1);
    
                if (enc3 != 64)
                {
                    output = output + String.fromCharCode(chr2);
                }
    
                if (enc4 != 64)
                {
                    output = output + String.fromCharCode(chr3);
                }
    
            } // Whend 
    
            output = Base64._utf8_decode(output);
    
            return output;
        } // End Function decode 
    
    
        // private method for UTF-8 encoding
        ,_utf8_encode: function (string)
        {
            var utftext = "";
            string = string.replace(/
    /g, "
    ");
    
            for (var n = 0; n < string.length; n++)
            {
                var c = string.charCodeAt(n);
    
                if (c < 128)
                {
                    utftext += String.fromCharCode(c);
                }
                else if ((c > 127) && (c < 2048))
                {
                    utftext += String.fromCharCode((c >> 6) | 192);
                    utftext += String.fromCharCode((c & 63) | 128);
                }
                else
                {
                    utftext += String.fromCharCode((c >> 12) | 224);
                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                    utftext += String.fromCharCode((c & 63) | 128);
                }
    
            } // Next n 
    
            return utftext;
        } // End Function _utf8_encode 
    
        // private method for UTF-8 decoding
        ,_utf8_decode: function (utftext)
        {
            var string = "";
            var i = 0;
            var c, c1, c2, c3;
            c = c1 = c2 = 0;
    
            while (i < utftext.length)
            {
                c = utftext.charCodeAt(i);
    
                if (c < 128)
                {
                    string += String.fromCharCode(c);
                    i++;
                }
                else if ((c > 191) && (c < 224))
                {
                    c2 = utftext.charCodeAt(i + 1);
                    string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                    i += 2;
                }
                else
                {
                    c2 = utftext.charCodeAt(i + 1);
                    c3 = utftext.charCodeAt(i + 2);
                    string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                    i += 3;
                }
    
            } // Whend 
    
            return string;
        } // End Function _utf8_decode 
    
    }


     
  • 相关阅读:
    topk 问题 --转载
    MySQL是否使用外键
    MySQL的事务隔离---总结和转载
    MySQL设计规范--转自腾讯云社区
    docker图解--转载
    单点登录soo-转载
    在linux上配置后端所需的内容
    推荐一个计算机漫画地址
    python与mysql数据库连接中常见错误
    python_excel_读写(转载)
  • 原文地址:https://www.cnblogs.com/youmingkuang/p/11828148.html
Copyright © 2011-2022 走看看