How can you encode a string to Base64 in JavaScript?

前端 未结 26 3817
梦如初夏
梦如初夏 2020-11-21 04:02

I have a PHP script that can encode a PNG image to a Base64 string.

I\'d like to do the same thing using JavaScript. I know how to open files, but I\'m not sure how

26条回答
  •  無奈伤痛
    2020-11-21 05:06

    I needed encoding of an UTF-8 string as base64 for a project of mine. Most of the answers here don't seem to properly handle UTF-16 surrogate pairs when converting to UTF-8 so, for completion sake, I will post my solution:

    function strToUTF8Base64(str) {
    
        function decodeSurrogatePair(hi, lo) {
            var resultChar = 0x010000;
            resultChar += lo - 0xDC00;
            resultChar += (hi - 0xD800) << 10;
            return resultChar;
        }
    
        var bytes = [0, 0, 0];
        var byteIndex = 0;
        var result = [];
    
        function output(s) {
            result.push(s);
        }
    
        function emitBase64() {
    
            var digits =
                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
                    'abcdefghijklmnopqrstuvwxyz' +
                    '0123456789+/';
    
            function toDigit(value) {
                return digits[value];
            }
    
            // --Byte 0--    --Byte 1--    --Byte 2--
            // 1111  1122    2222  3333    3344  4444
    
            var d1 = toDigit(bytes[0] >> 2);
            var d2 = toDigit(
                ((bytes[0] & 0x03) << 4) |
                (bytes[1] >> 4));
            var d3 = toDigit(
                ((bytes[1] & 0x0F) << 2) |
                (bytes[2] >> 6));
            var d4 = toDigit(
                bytes[2] & 0x3F);
    
            if (byteIndex === 1) {
                output(d1 + d2 + '==');
            }
            else if (byteIndex === 2) {
                output(d1 + d2 + d3 + '=');
            }
            else {
                output(d1 + d2 + d3 + d4);
            }
        }
    
        function emit(chr) {
            bytes[byteIndex++] = chr;
            if (byteIndex == 3) {
                emitBase64();
                bytes[0] = 0;
                bytes[1] = 0;
                bytes[2] = 0;
                byteIndex = 0;
            }
        }
    
        function emitLast() {
            if (byteIndex > 0) {
                emitBase64();
            }
        }
    
        // Converts the string to UTF8:
    
        var i, chr;
        var hi, lo;
        for (i = 0; i < str.length; i++) {
            chr = str.charCodeAt(i);
    
            // Test and decode surrogate pairs in the string
            if (chr >= 0xD800 && chr <= 0xDBFF) {
                hi = chr;
                lo = str.charCodeAt(i + 1);
                if (lo >= 0xDC00 && lo <= 0xDFFF) {
                    chr = decodeSurrogatePair(hi, lo);
                    i++;
                }
            }
    
            // Encode the character as UTF-8.
            if (chr < 0x80) {
                emit(chr);
            }
            else if (chr < 0x0800) {
                emit((chr >> 6) | 0xC0);
                emit(((chr >> 0) & 0x3F) | 0x80);
            }
            else if (chr < 0x10000) {
                emit((chr >> 12) | 0xE0);
                emit(((chr >>  6) & 0x3F) | 0x80);
                emit(((chr >>  0) & 0x3F) | 0x80);
            }
            else if (chr < 0x110000) {
                emit((chr >> 18) | 0xF0);
                emit(((chr >> 12) & 0x3F) | 0x80);
                emit(((chr >>  6) & 0x3F) | 0x80);
                emit(((chr >>  0) & 0x3F) | 0x80);
            }
        }
    
        emitLast();
    
        return result.join('');
    }
    

    Note that the code is not thoroughly tested. I tested some inputs, including things like strToUTF8Base64('衠衢蠩蠨') and compared with the output of an online encoding tool (https://www.base64encode.org/).

提交回复
热议问题