эквивалент php base64_decode в javascript [дубликат]

Объявление функции и выражение функции, присваиваемое переменной, ведут себя одинаково после установления привязки.

Однако существует , как и , когда объект функции фактически связан с его переменной. Это различие связано с механизмом, называемым изменением подъема в JavaScript.

В принципе, все объявления функций и объявления переменных поднимаются в начало функции в котором происходит объявление (поэтому мы говорим, что JavaScript имеет область функций ).

  • Когда объявление функции поднимается, тело функции «следует», поэтому, когда тело функции оценивается, переменная сразу будет привязана к объекту функции.
  • Когда объявление переменной вставлено, инициализация выполняет не , но «остается позади», , Переменная инициализируется в undefined в начале тела функции и будет присвоена значение в исходном месте в коде. (На самом деле ему будет присвоено значение в в каждом месте, где появляется объявление переменной с тем же именем.)

Порядок подъема также важен : объявления функций имеют приоритет над объявлениями переменных с тем же именем, а последнее объявление функции имеет приоритет над предыдущими объявлениями с таким же именем.

Некоторые примеры ...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

Переменная foo поднимается в начало функции, инициализируется на undefined, так что !foo является true, поэтому foo назначается 10. foo вне области bar не играет никакой роли и нетронутой.

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

Объявление функций имеет приоритет над объявлениями переменных, а последнее объявление функции «прилипает».

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

В этом примере инициализируется a с результатом функции от оценки объявления второй функции, а затем назначается 4.

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}}
b();
a // 1

Здесь объявление функции сначала открывается, объявляя и инициализируя переменную a. Затем этой переменной присваивается 10. Другими словами: присваивание не присваивается внешней переменной a.

635
задан username 6 June 2013 в 21:06
поделиться

21 ответ

Вы можете использовать btoa() и atob() для преобразования в кодировку base64 и из нее.

Кажется, что есть некоторая путаница в комментарии относительно того, что эти функции принимают / возвращают, поэтому ...

  • btoa() принимает «строку», где каждый символ представляет 8-разрядный байт - если вы передаете строку, содержащую символы, которые не могут быть представленным в 8 бит, он, вероятно, сломается . Это не проблема , если вы фактически обрабатываете строку как массив байтов, но если вы пытаетесь сделать что-то еще, вам сначала нужно закодировать ее.
  • atob() возвращает строку, в которой каждый символ представляет 8-разрядный байт, то есть его значение будет находиться между 0 и 0xff. Это означает, что not означает, что это ASCII - предположительно, если вы вообще используете эту функцию, вы ожидаете работать с двоичными данными, а не с текстом.

См. Также :

652
ответ дан Rehan Haider 21 August 2018 в 13:41
поделиться
  • 1
    Обратите внимание, что это также работает для веб-браузеров, таких как Safari. – Daniel Von Fange 2 September 2010 в 10:59
  • 2
    но он не работает на iPhone3G с iOS 4.1. Он работает на симуляторе симулятора iPhone, когда он установлен на iPhone4 или iPhone. – Grant M 15 September 2010 в 09:38
  • 3
    Обратите внимание на особое внимание к строкам Unicode: developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa и atob работают только для строк на основе ASCII. Как американец, вы, вероятно, не заметите разницы ... но в первый раз, когда вы используете акцентированный характер, ваш код сломается. – Dan Esparza 8 November 2011 в 18:23
  • 4
    вы должны использовать btoa(unescape(encodeURIComponent(str)))), если str - UFT8 – SET 15 May 2013 в 08:49
  • 5

Вот версия версии AngularJS Factory @ user850789:

'use strict';

var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []);

ProjectNameBase64Factory.factory('Base64', function () {
    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 +
                         Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
                         Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);

            }

            return output;
        },

        // 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 = Base64._keyStr.indexOf(input.charAt(i++));
                enc2 = Base64._keyStr.indexOf(input.charAt(i++));
                enc3 = Base64._keyStr.indexOf(input.charAt(i++));
                enc4 = Base64._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);
                }

            }

            output = Base64._utf8_decode(output);

            return output;

        },

        // private method for UTF-8 encoding
        _utf8_encode: function (string) {
            string = string.replace(/\r\n/g, "\n");
            var utftext = "";

            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);
                }

            }

            return utftext;
        },

        // private method for UTF-8 decoding
        _utf8_decode: function (utftext) {
            var string = "";
            var i = 0;
            var c = 0, c2 = 0, c3 = 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;
                }

            }
            return string;
        }
    };
    return Base64;
});
5
ответ дан A T 21 August 2018 в 13:41
поделиться

Ну, если вы используете додзё, это дает нам прямой способ кодирования или декодирования в base64.

Попробуйте следующее: -

Чтобы закодировать массив байтов с помощью dojox. encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

Чтобы декодировать строку с кодировкой base64:

var bytes = dojox.encoding.base64.decode(str);
4
ответ дан Camilo Terevinto 21 August 2018 в 13:41
поделиться

Из комментариев (по SET и Stefan Steiger) ниже принятого ответа, вот краткий обзор того, как кодировать / декодировать строку в / из base64 без необходимости библиотеки.

str = "The quick brown fox jumps over the lazy dog";
b64 = btoa(unescape(encodeURIComponent(str)));
str = decodeURIComponent(escape(window.atob(b64)));

Demo

(использует библиотеку jQuery, но не для кодирования / декодирования)

str = "The quick brown fox jumps over the lazy dog";

$('input').val(str);

$('#btnConv').click(function(){
  var txt = $('input').val();
  var b64 = btoa(unescape(encodeURIComponent(txt)));
  $('input').val(b64);
  $('#btnDeConv').show();
});
$('#btnDeConv').click(function(){
  var b64 = $('input').val();
  var txt = decodeURIComponent(escape(window.atob(b64)));
  $('input').val(txt);
});
#btnDeConv{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" />
<button id="btnConv">Convert</button>
<button id="btnDeConv">DeConvert</button>

15
ответ дан Crashalot 21 August 2018 в 13:41
поделиться
  • 1
    Для подтверждения это поддерживает символы UTF-8? – Crashalot 3 February 2018 в 10:09

Я предпочел бы использовать методы кодирования / декодирования bas64 из CryptoJS , самой популярной библиотеки для стандартных и безопасных криптографических алгоритмов, реализованных в JavaScript с использованием лучших практик и шаблонов.

5
ответ дан Dan Dascalescu 21 August 2018 в 13:41
поделиться

Internet Explorer 10 +

// Define the string
var string = 'Hello World!';

// Encode the String
var encodedString = btoa(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = atob(encodedString);
console.log(decodedString); // Outputs: "Hello World!"

Перекрестный браузер

// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}

// Define the string
var string = 'Hello World!';

// Encode the String
var encodedString = Base64.encode(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = Base64.decode(encodedString);
console.log(decodedString); // Outputs: "Hello World!"

jsFiddle


] с Node.js

Вот как вы кодируете обычный текст в base64 в Node.js:

//Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter. 
// Default is utf8, possible encoding types are ascii, utf8, ucs2, base64, binary, and hex
var b = new Buffer('JavaScript');
// If we don't use toString(), JavaScript assumes we want to convert the object to utf8.
// We can make it convert to other formats by passing the encoding type to toString().
var s = b.toString('base64');

И вот как вы декодируете строки с кодировкой base64:

var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();

с Dojo.js

Чтобы закодировать массив байтов с помощью dojox.encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

Чтобы декодировать строку с кодировкой base64 :

var bytes = dojox.encoding.base64.decode(str)

bower install angular-base64

<script src="bower_components/angular-base64/angular-base64.js"></script>

angular
    .module('myApp', ['base64'])
    .controller('myController', [

    '$base64', '$scope', 
    function($base64, $scope) {

        $scope.encoded = $base64.encode('a string');
        $scope.decoded = $base64.decode('YSBzdHJpbmc=');
}]);
84
ответ дан davidcondrey 21 August 2018 в 13:41
поделиться
  • 1
    Этот ответ основан на исходном коде и НЕ включает обновления этого кода, размещенные в других ответах здесь. – Eugene Ryabtsev 27 November 2014 в 11:15

Ответ I + 1 ответил Солнышко, но я хотел внести несколько изменений, которые я сделал для своего проекта, если кто-то найдет его полезным. В основном, я только что немного очистил исходный код, поэтому JSLint не жалуется так же сильно, и я сделал методы, помеченные как частные в комментариях, фактически закрытых. Я также добавил два метода, которые мне нужны в моем собственном проекте, а именно decodeToHex и encodeFromHex.

Код:

var Base64 = (function() {
    "use strict";

    var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    var _utf8_encode = function (string) {

        var utftext = "", c, n;

        string = string.replace(/\r\n/g,"\n");

        for (n = 0; n < string.length; n++) {

            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);

            }

        }

        return utftext;
    };

    var _utf8_decode = function (utftext) {
        var string = "", i = 0, c = 0, c1 = 0, c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {

                string += String.fromCharCode(c);
                i++;

            } else if((c > 191) && (c < 224)) {

                c1 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                i += 2;

            } else {

                c1 = utftext.charCodeAt(i+1);
                c2 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                i += 3;

            }

        }

        return string;
    };

    var _hexEncode = function(input) {
        var output = '', i;

        for(i = 0; i < input.length; i++) {
            output += input.charCodeAt(i).toString(16);
        }

        return output;
    };

    var _hexDecode = function(input) {
        var output = '', i;

        if(input.length % 2 > 0) {
            input = '0' + input;
        }

        for(i = 0; i < input.length; i = i + 2) {
            output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16));
        }

        return output;
    };

    var encode = function (input) {
        var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

        input = _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 += _keyStr.charAt(enc1);
            output += _keyStr.charAt(enc2);
            output += _keyStr.charAt(enc3);
            output += _keyStr.charAt(enc4);

        }

        return output;
    };

    var decode = function (input) {
        var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = _keyStr.indexOf(input.charAt(i++));
            enc2 = _keyStr.indexOf(input.charAt(i++));
            enc3 = _keyStr.indexOf(input.charAt(i++));
            enc4 = _keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output += String.fromCharCode(chr1);

            if (enc3 !== 64) {
                output += String.fromCharCode(chr2);
            }
            if (enc4 !== 64) {
                output += String.fromCharCode(chr3);
            }

        }

        return _utf8_decode(output);
    };

    var decodeToHex = function(input) {
        return _hexEncode(decode(input));
    };

    var encodeFromHex = function(input) {
        return encode(_hexDecode(input));
    };

    return {
        'encode': encode,
        'decode': decode,
        'decodeToHex': decodeToHex,
        'encodeFromHex': encodeFromHex
    };
}());
15
ответ дан Joe Dyndale 21 August 2018 в 13:41
поделиться
  • 1
    Первоначально я думал, что ваше разворачивание конкатенации вывода в отдельные утверждения было бы более оптимальным, но после того, как я подумал об этом в течение секунды, этот должен быть более неэффективным, поскольку строки Javascript неизменяемы, и это приведет к 4 копиям потенциально огромных капель данных при работе с большими двоичными файлами данных. Это более безопасная ставка, чтобы объединить четыре символа вместе, а затем построить новую строку. Хотелось бы, чтобы я знал наверняка лучший метод построения строк, который, несомненно, был бы эффективен на всех платформах. (даже IE6) – Marius 4 January 2013 в 20:19
  • 2
    Я не рассматривал производительность при очистке исходного кода. Я просто сделал его более читаемым и сделал методы, помеченные как частные в комментариях в оригинале, фактически были частными, используя шаблон раскрывающего модуля. Я уверен, что он может быть оптимизирован в отношении производительности. Не совсем уверен, когда сбор мусора начнется здесь, а хеширование больших файлов через Javascript не очень распространено (или, скорее всего, не оптимальное решение в любом случае). – Joe Dyndale 7 January 2013 в 13:39
  • 3
    Забавно, как этот код живет здесь. На этой странице уже есть 3 разных версии. – gregn3 7 March 2014 в 14:37

Внесение в файл window.atob + window.btoa, который я использую в настоящее время в файле minified polyfill.

(function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
6
ответ дан Johan 21 August 2018 в 13:41
поделиться

Этот вопрос и ответы дали мне направление в правильном направлении. Специально с unicode atob и btoa нельзя использовать «ваниль», и в эти дни все равно unicode ..

Непосредственно из Mozilla две хорошие функции для этой цели (протестированы с помощью юникода и html-тегов внутри)

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64EncodeUnicode('\n'); // "Cg=="



function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
b64DecodeUnicode('Cg=='); // "\n"

Эти функции будут выполнять молниеносно по сравнению с необработанным декодированием base64, используя пользовательскую функцию javascript, поскольку btoa и atob выполняются вне интерпретатора.

Если вы можете игнорировать старый IE и старый мобильный телефоны (например, iphone 3?) это должно быть хорошим решением.

8
ответ дан John 21 August 2018 в 13:41
поделиться

Обратите внимание, что это не подходит для сырых строк Unicode! См. Раздел Unicode здесь .

Синтаксис для кодирования

var encodedData = window.btoa(stringToEncode);

Синтаксис для декодирования

var decodedData = window.atob(encodedData);

9
ответ дан Kathir 21 August 2018 в 13:41
поделиться

Чтобы создать URL-адрес, закодированный в кодировке Base64, в JavaScript вы можете сделать что-то вроде этого:

// if this is your Base64 encoded string
var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; 

// make URL friendly:
str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');

// reverse to original encoding
str = (str + '===').slice(0, str.length + (str.length % 4));
str = str.replace(/-/g, '+').replace(/_/g, '/');

См. также этот скрипт: http://jsfiddle.net/magikMaker/7bjaT /

12
ответ дан magikMaker 21 August 2018 в 13:41
поделиться
  • 1
    Я смиренно предположил бы, что использование encodeURIComponent вполне может привести к превосходному результату с меньшими затратами усилий со стороны разработчика. – Pablo Fernandez 28 October 2011 в 17:22
  • 2
    encodeURIComponent изменит длину строк с кодировкой base64, а замена «-» и «_» на «+» и «/» является стандартной практикой при использовании base64 в URL-адресах (например, docs.python.org/library/base64. HTML # base64.urlsafe_b64encode ). Не нужно расстраиваться. – natevw 22 December 2011 в 19:29

Если вам нужно больше работать, если вы хотите использовать высокопроизводительное собственное решение, вы можете использовать некоторые функции HTML5.

Если вы можете получить свои данные в Blob , вы можете использовать функцию FileReader.readAsDataURL () , чтобы получить URL data:// и отрубить переднюю часть, чтобы получить данные базы64.

Вы можете нужно выполнить дальнейшую обработку, но для urldecode данных, так как я не уверен, что символы + экранированы или нет для URL data://, но это должно быть довольно тривиально.

4
ответ дан Malvineous 21 August 2018 в 13:41
поделиться

, если вам нужно закодировать объект изображения HTML, вы можете написать простую функцию, например:

function getBase64Image(img) {  
  var canvas = document.createElement("canvas");  
  canvas.width = img.width;  
  canvas.height = img.height;  
  var ctx = canvas.getContext("2d");  
  ctx.drawImage(img, 0, 0);  
  var dataURL = canvas.toDataURL("image/png");  
  // escape data:image prefix
  return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");  
  // or just return dataURL
  // return dataURL
}  

Получить base64 изображения по id:

function getBase64ImageById(id){  
  return getBase64Image(document.getElementById(id));  
} 

more здесь

9
ответ дан Nedudi 21 August 2018 в 13:41
поделиться

Для моего проекта мне все еще нужно поддерживать IE7 и работать с большим вводом для кодирования.

На основе кода, предложенного Джо Дайддейлом, и, как было предложено в комментарии Мариуса, можно улучшить производительность с IE7, построив результат с помощью массива вместо строки.

Вот пример для кодирования:

var encode = function (input) {
    var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;

    input = _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.push(_keyStr.charAt(enc1));
        output.push(_keyStr.charAt(enc2));
        output.push(_keyStr.charAt(enc3));
        output.push(_keyStr.charAt(enc4));

    }

    return output.join("");
};
4
ответ дан Nico 21 August 2018 в 13:41
поделиться

Я переписал вручную эти методы кодирования и декодирования, за исключением шестнадцатеричного, в модульный формат для совместимости с кросс-платформой / браузером, а также с реальной частной областью видимости и использует btoa и atob если они существуют из-за скорости, а не используют собственную кодировку:

https://gist.github.com/Nijikokun/5192472

Использование:

base64.encode(/* String */);
base64.decode(/* String */);

utf8.encode(/* String */);
utf8.decode(/* String */);
11
ответ дан Nijikokun 21 August 2018 в 13:41
поделиться

Мне понадобилось кодирование строки UTF-8 в качестве base64 для моего проекта. Большинство ответов здесь, похоже, не обрабатывают суррогатные пары UTF-16 при преобразовании в UTF-8, поэтому, для завершения, я опубликую свое решение:

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('');
}

Обратите внимание, что код не прошли тщательную проверку. Я протестировал некоторые входы, включая такие вещи, как strToUTF8Base64('衠衢蠩蠨'), и сравнил с выходом онлайн-инструмента кодирования ( https://www.base64encode.org/ ).

5
ответ дан Ricardo Machado 21 August 2018 в 13:41
поделиться

В обеих реализациях _utf8_decode есть пара ошибок. c1 и c2 назначаются глобальными переменными из-за нарушения работы оператора var, а c3 не инициализируется и не объявляется вообще.

Он работает, но эти переменные будут перезаписаны любые существующие с тем же именем вне этой функции.

Вот версия, которая этого не сделает:

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var c = 0, c1 = 0, c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if((c > 191) && (c < 224)) {
            c1 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
            i += 2;
        }
        else {
            c1 = utftext.charCodeAt(i+1);
            c2 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
            i += 3;
        }

    }
    return string;
}
25
ответ дан robbles 21 August 2018 в 13:41
поделиться
  • 1
    Почему бы вам просто не обновить предыдущий ответ? – Daan 9 December 2013 в 17:52
  • 2
    @Daan У меня не хватило репутации для редактирования ответов, когда я написал этот ответ ... в 2011 году. – robbles 10 December 2013 в 19:42
  • 3
    IE7? я думаю, мы должны перестать тратить время на создание кода для этого, люди не перестанут использовать эту старую технологию, если мы не заставили их разработчиков! – Ronan Dejhero 7 June 2014 в 16:01
  • 4
    @RonanDejhero не работает в IE7? Я не помню, тестировал ли я в этом конкретном браузере. – robbles 8 June 2014 в 23:47
  • 5
    Что я имел в виду, если он не работает в IE7, никто не должен заботиться !. я не тестировал и не тестировал его :) – Ronan Dejhero 9 June 2014 в 12:02

Отсюда :

/**
*
*  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);

    }

    return output;
},

// 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);
        }

    }

    output = Base64._utf8_decode(output);

    return output;

},

// private method for UTF-8 encoding
_utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    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);
        }

    }

    return utftext;
},

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var 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;
        }

    }

    return string;
}

}

Кроме того, поиск по «кодировке javascript base64» включает в себя множество других опций, первый.

270
ответ дан Sunny Milenov 21 August 2018 в 13:41
поделиться
  • 1
    это работает с & lt; input type = "file & quot; / & gt; HTML-формы? – jordan.baucke 18 August 2011 в 00:28
  • 2
    Это также полезно, когда кодировка base64 нестандартна; в моем случае & quot; / & quot; символ не использовался, а символ & quot; & quot; вместо этого использовался символ, что означает, что даже в Chrome atob () не собирался декодировать строки base64, которые поступали. – Chris Moschini 17 December 2011 в 14:43
  • 3
    Будьте осторожны с этим кодом - он пытается интерпретировать вашу строку как кодированную строку UTF-8. У нас был случай, когда у нас была двоичная строка (т. Е. Каждый символ в строке должен интерпретироваться как байт), и этот код испортил данные. Прочтите источник, Люк. – Daniel Yankowsky 12 November 2012 в 20:27
  • 4
    Все, что необходимо для обеспечения безопасности для большинства двоичных кодировок / декодирования, позволяет удалить сомнительный оператор string = string.replace(/\r\n/g,"\n"); в методе кодирования utf8. – Marius 4 January 2013 в 19:59
  • 5
    @Marius: Мне интересно, почему они вообще включили string = string.replace(/\r\n/g,"\n");, lol. Это как «о, давайте закодировать эту строку, но во-первых, почему бы нам просто не произвольно нормализовать все разрывы строк без какой-либо веской причины». Это должно быть абсолютно удалено из класса при любых обстоятельствах. – Triynko 6 August 2013 в 23:40

Код Sunny - отличный, за исключением того, что он разбивается на IE7 из-за ссылок на «this». Исправлено заменой таких ссылок на «Base64»:

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 +
        Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
        Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);

    }

    return output;
},

// 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 = Base64._keyStr.indexOf(input.charAt(i++));
        enc2 = Base64._keyStr.indexOf(input.charAt(i++));
        enc3 = Base64._keyStr.indexOf(input.charAt(i++));
        enc4 = Base64._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);
        }

    }

    output = Base64._utf8_decode(output);

    return output;

},

// private method for UTF-8 encoding
_utf8_encode : function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";

    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);
        }

    }

    return utftext;
},

// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
    var string = "";
    var i = 0;
    var 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;
        }

    }
    return string;
}
}
90
ответ дан user850789 21 August 2018 в 13:41
поделиться
  • 1
    ooh мой плохой, я принимал входные данные из URL-адреса браузера; где | преобразуется в% 7C; поэтому кодирование также неверно. – Kanagavelu Sugumar 11 September 2013 в 09:03
  • 2
    Я знаю, что это действительно старо, но я видел, что эта функция используется в более чем одном месте, ключевая строка на самом деле имеет 65 символов, а не 64. Строка не стандартная спецификация, я не уверен, что это имеет значение, но было просто интересно если это так? – Jonathan Wagner 17 June 2015 в 04:17
  • 3
    «использовать строгий»; это то, что разрушает «этот» и другие элементы типа «с» и из того, что я прочитал, «eval» получает избиение. Все неуместные идеи о злоупотреблениях. Лично я не понимаю, почему JavaScript должен идти по маршруту, это никогда не предназначалось для того, чтобы программа была тесно связана и сложнее, чем она уже есть. Если вы хотите быть связанными, создайте компилятор для javascript. – Mark Giblin 10 October 2015 в 12:30
  • 4
    Я пытаюсь использовать эту функцию, и я получаю сообщение об ошибке: Caused by: org.mozilla.javascript.EcmaError: TypeError: не удается найти функцию replace в teste teste teste teste Я пытаюсь кодировать .txt с teste teste teste. Кто-нибудь знает, почему эта ошибка? – PRVS 4 November 2015 в 10:19
  • 5
    @JonathanWagner - для нормальной кодировки используется 64 символа. 65-й ​​символ используется как заполнение их входной строки не имеет числа символов, делящихся на 3. – Kickstart 5 September 2017 в 13:58

Вы можете использовать btoa (до base-64) и atob (от base-64).

Для IE 9 и ниже попробуйте плагин jquery-base64 :

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
86
ответ дан Vitalii Fedorenko 21 August 2018 в 13:41
поделиться
  • 1
    Почему все должно быть плагином jQuery: c это просто базовая функциональность JavaScript, это не имеет ничего общего с DOM или jQuery – EaterOfCode 29 April 2013 в 12:04
  • 2
    Это не основная функциональность, или не было бы так много разных высоких голосовых ответов (включая код do-it-yourself tl; dr). Итак, imho это на самом деле хороший вариант использования jQuery (один лайнер, который, как ожидается, будет работать даже в Android-браузере Android), даже если это уже зависимость. – Risadinha 26 August 2013 в 18:04
  • 3
    Мне нравится устанавливать фрагменты кода, подобные этому в jQuery, главным образом потому, что они будут существовать в контролируемом пространстве имен. Если вы не используете AMD или CommonJS или аналогичный шаблон дизайна, ваше глобальное пространство имен просто станет бесполезным с кучей случайных функций. – sffc 25 June 2014 в 08:23
  • 4
    @Risadinha - за исключением того, что ее функциональность не зависит ни от какого-либо jQuery, ни от каких-либо расширений ... буквально единственные ссылки на jQuery в его коде прикрепляют его к объекту jQuery ... так что в чем смысл прикреплять его к jQuery и поэтому требует Использовать jQuery? Просто сделайте это своим собственным лайнером base64.encode(...) и base64.decode(...) ... прикрепляя его к jQuery, когда он имеет нулевую специфику jQuery, не имеет абсолютно никакого смысла ... – Jimbo Jonny 12 March 2016 в 06:28
  • 5
    jQuery не запрашивался. Недействительный ответ на простой старый вопрос JS. – metaColin 10 February 2017 в 23:20
0
ответ дан Alireza 1 November 2018 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: