JavaScript에서 문자열을 Base64로 어떻게 인코딩 할 수 있습니까?


809

PNG 이미지를 Base64 문자열로 인코딩 할 수있는 PHP 스크립트가 있습니다.

JavaScript를 사용하여 동일한 작업을 수행하고 싶습니다. 파일을 여는 방법을 알고 있지만 인코딩 방법을 잘 모르겠습니다. 이진 데이터 작업에 익숙하지 않습니다.


2
다음은 javascript를 사용하여 base64_encode 및 base64_decode하는 가장 좋은 방법입니다. 아래 링크를 참조하십시오. phpjs.org/functions/base64_encode:358 phpjs.org/functions/base64_decode:357
gautamlakum

다음은 base64 인 코드 / 디코딩을위한 또 다른 jquery 플러그인입니다.
zahid9i


답변:


865

base64 인코딩을 사용 btoa()하거나 atob()base64 인코딩으로 변환 할 수 있습니다 .

이 함수들이 무엇을 수락 / 반환하는지에 대한 의견에는 약간의 혼동이있는 것 같습니다.

  • btoa()각 문자가 8 비트 바이트를 나타내는 "문자열"을 허용합니다. 8 비트로 표현할 수없는 문자가 포함 된 문자열을 전달하면 깨질 수 있습니다. 실제로 문자열을 바이트 배열로 취급하는 경우 에는 문제가되지 않지만 다른 작업을 수행하려는 경우 먼저 인코딩해야합니다.

  • atob()각 문자가 8 비트 바이트를 나타내는 "문자열"을 반환합니다. 즉, 값은 ~ 사이 00xff있습니다. 그렇다고 ASCII 가 아님을 의미하는 것은 아닙니다. 아마도이 기능을 전혀 사용하지 않는다면 텍스트가 아닌 이진 데이터로 작업 할 것으로 예상됩니다.

또한보십시오:


47
Safari와 같은 웹킷 브라우저에서도 작동합니다.
Daniel Von Fange

5
그러나 iOS 4.1이 설치된 iPhone3G에서는 작동하지 않습니다. iPhone4 또는 iPhone으로 설정하면 시뮬레이터 iPhone 시뮬레이터에서 작동합니다.
Grant M

29
유니 코드 문자열을 특별히 고려해야합니다. developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa 및 atob은 ASCII 기반 문자열에 대해서만 제대로 작동합니다. 미국인이라면 아마도 차이를 느끼지 못할 것입니다 ...하지만 악센트 문자를 처음 사용하면 코드가 깨집니다.
Dan Esparza

70
btoa(unescape(encodeURIComponent(str))))str이 UFT8 인 경우 사용해야 합니다.
SET

4
내 편집, @Triynko를 참조하십시오. 텍스트 , 마침표 를 처리하는 데 사용되지는 않습니다 .
Shog9

289

여기에서 :

/**
*
*  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 encoding" 에 대한 검색 은 다른 많은 옵션으로 바뀌 었습니다. 위의 첫 번째 옵션이었습니다.


3
base64 인코딩이 비표준 인 경우에도 유용합니다. 제 경우에는 "/"문자가 사용되지 않았고 "?" 문자가 대신 사용되었으므로 Chrome에서도 atob ()이 들어오는 base64 문자열을 디코딩하지 않습니다.
Chris Moschini

21
이 코드를 조심하십시오-문자열을 UTF-8 인코딩 문자열로 해석하려고 시도합니다. 바이너리 문자열이있는 경우 (즉, 문자열의 각 문자를 바이트로 해석해야 함)이 코드가 데이터를 손상 시켰습니다. 출처를 읽으십시오, 루크.
다니엘 Yankowsky

11
대부분의 이진 인코딩 / 디코딩에서 안전을 유지하는 데 필요한 모든 것은 string = string.replace(/\r\n/g,"\n");utf8 인코딩 방법에서 의심스러운 문 을 제거합니다 .
Marius

7
@Marius : 왜 그들이 string = string.replace(/\r\n/g,"\n");처음부터 롤을 포함하는지 궁금 합니다. "아,이 문자열을 인코딩하자. 그러나 우선, 아무 이유없이 모든 줄 바꿈을 무작위로 정규화하지 않는 이유는 무엇입니까?" 모든 상황에서 수업에서 완전히 삭제해야합니다.
Triynko

2
나는 자바 스크립트 전문가가 아니지만이 코드에는 버그가있는 것 같습니다 : chr2가 NaN 인 경우 그 값은 여전히 ​​문에 사용됩니다 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);. 내 브라우저에서 이것은 NaN>>4정상적으로 작동 하지만 0 과 동일하지만 모든 브라우저 가이 작업을 수행하는지 (또는 NaN/16NaN 과 같은지) 알 수 없습니다 .
Jan

117

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로

Node.js에서 일반 텍스트를 base64로 인코딩하는 방법은 다음과 같습니다.

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

바우처 설치 앵귤러베이스 64

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

3
이 답변은 원래 코드를 기반으로하며 여기에 다른 답변에 게시 된 해당 코드에 대한 업데이트는 포함되지 않습니다.
유진 Ryabtsev

제안 된 NodeJS 솔루션은 더 이상 사용되지 않습니다.
Vladimir Nul

94

Sunny의 코드는 "this"에 대한 참조로 인해 IE7에서 중단되는 것을 제외하고는 훌륭합니다. 이러한 참조를 "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;
}
}

4
내 나쁜, 나는 브라우저 URL에서 입력을 받고 있었다; 어디 | % 7C로 변환되고; 따라서 인코딩도 잘못되었습니다.
Kanagavelu Sugumar

나는 이것이 실제로 오래되었다는 것을 알고 있지만이 기능이 두 곳 이상에서 사용되는 것을 보았습니다. 키 문자열은 실제로 64자가 아닌 65 자입니다. 문자열은 표준 사양이 아니며 중요하지는 않지만 확실하지는 않습니다. 만약 그렇다면?
Jonathan Wagner

"엄격한 사용"; 'this'와 'with'와 같은 다른 유형 요소를 깨뜨리고 내가 읽은 것에서 'eval'은 강타를 얻습니다. 학대에 관한 모든 잘못된 아이디어. 개인적으로 JavaScript가 진행되는 경로를 내려야하는 이유를 알지 못합니다.이 프로그램은 단단히 묶여 있고 이미보다 복잡하게 만들어지지 않았습니다. 바인딩하고 싶다면 자바 스크립트 컴파일러를 만드십시오.
Mark Giblin

이 함수를 사용하려고하면 오류가 발생합니다. 원인 : org.mozilla.javascript.EcmaError : TypeError : 개체 teste teste teste에서 함수 replace를 찾을 수 없습니다. .txt를 "teste teste teste"로 인코딩하려고합니다. 이 오류가 왜 발생했는지 아는 사람이 있습니까?
PRVS

@JonathanWagner-일반 인코딩에 64자가 사용됩니다. 65 번째 문자는 패딩으로 사용되며 입력 문자열에는 3으로 나눌 수있는 문자 수가 없습니다.
Kickstart

90

btoa(base-64) 및 atob( base-64)를 사용할 수 있습니다 .

IE 9 이하의 경우 jquery-base64 플러그인을 사용해보십시오 .

$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");

133
왜 jQuery 플러그인으로 모든 필요를 수행합니다 이것은 단지의 핵심 자바 스크립트 기능이는 C 이것은 DOM이나 jQuery를 함께 할 수있는 아무것도 없다
EaterOfCode

38
이것은 핵심 기능이 아니거나 투표율이 높은 다른 답변이 많지 않습니다 (Do-it-yourself tl; dr 코드 포함). 따라서 imho는 실제로 jQuery (Android의 WebView에서도 작동 할 것으로 예상되는 하나의 라이너)의 좋은 유스 케이스입니다. 이미 종속성 인 경우 훨씬 더 많습니다.
Risadinha

1
제어 된 네임 스페이스에 존재하기 때문에 이와 같은 코드 스 니펫을 jQuery에 설치하고 싶습니다. AMD 또는 CommonJS 또는 이와 유사한 디자인 패턴을 사용하지 않는 경우 전역 네임 스페이스가 임의의 함수로 인해 복잡해지기 쉽습니다.
sffc

9
@Risadinha-기능을 제외하고는 jQuery에 전혀 의존하지 않거나 확장하지 않습니다 ... 문자 그대로 jQuery에 대한 유일한 참조는 jQuery 객체에 첨부하는 것입니다 ... 그래서 jQuery에 첨부하는 요점 사용할 jQuery? 그냥 1 라이너가 자신의 그것을 확인 base64.encode(...)하고 base64.decode(...)제로의 jQuery 특정 기능이 ... 전혀 이해되지 않는다 때 ... jQuery를에 부착
짐보 조니

1
jQuery가 요청되지 않았습니다. 평범한 JS 질문에 대한 올바른 답변이 아닙니다.
metaColin

34

허용 된 답변 아래의 주석 (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)));

데모

(jQuery 라이브러리를 사용하지만 인코딩 / 디코딩에는 사용하지 않음)


확인하려면 UTF-8 문자를 지원합니까?
Crashalot

1
@Crashalot 나는 이것이 2 년이 너무 늦다는 것을 알고 있지만 그렇습니다. UTF8이 작동하도록 편집을 제공했다는 것을 입력하면서 실현하고 있습니다.
tycrek

Node.js와 함께 사용하기에 좋은 솔루션을 찾고있는 사람이라면 누구나이 작업을 확인할 수 있습니다. Node에서 디코딩을 위해 다음을 사용했습니다.Buffer.from(b64data, 'base64').toString();
tycrek at

26

의 두 가지 구현에는 몇 가지 버그가 있습니다 _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;
}

9
@Daan 2011 년에이 답변을 쓸 때 답변을 편집 할 충분한 담당자가 없습니다.
robbles

2
IE7? 나는 우리가 코드를 작성하는 데 시간을 낭비하지 말아야한다고 생각합니다. 개발자가 강제로하지 않으면 사람들은이 오래된 기술을 사용하지 않을 것입니다!
Rami Dabain 2016 년

@RonanDejhero는 IE7에서 작동하지 않습니까? 특정 브라우저에서 테스트했는지 기억이 없습니다.
robbles 2016 년

1
내가 IE7에서 작동하지 않으면 아무도 신경 쓰지 않아야한다는 것을 의미했습니다!. 나는 테스트하지 않았고 테스트하지 않을 것입니다 :)
Rami Dabain

16

나는 Sunny의 답변을 +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
    };
}());

처음에는 출력 연결을 별도의 문으로 언롤하는 것이 더 최적이라고 생각했지만 잠시 동안 생각한 후에 는 자바 스크립트 문자열을 변경할 수 없으므로 작업 할 때 잠재적으로 거대한 데이터 얼룩의 사본을 4 개 만들 수 있으므로 더 비효율적 이어야 합니다 큰 이진 데이터 파일로. 4 개의 문자를 먼저 연결 한 다음 새 문자열을 만드는 것이 더 안전합니다. 모든 플랫폼에서 효율적으로 작동하는 더 나은 문자열 작성 방법을 알고 싶습니다. (심지어 IE6)
Marius

원래 게시 된 코드를 정리할 때 성능을 고려하지 않았습니다. 방금 공개 모듈 패턴을 사용하여 더 읽기 쉽고 원본의 주석에서 개인으로 표시된 메소드를 비공개로 만들었습니다. 성능과 관련하여 최적화 될 수 있다고 확신합니다. 가비지 수집이 언제 시작되는지 확실하지 않으며 Javascript를 통해 큰 파일을 해시하는 것은 그리 일반적이지 않습니다 (또는 실제로는 최적의 솔루션이 아닐 수도 있음).
Joe Dyndale

이 코드가 어떻게 생겼는지 재밌습니다. 이 페이지에는 이미 3 가지 버전이 있습니다.
gregn3

15

최신 브라우저에서 Uint8Array를 문자열로 인코딩하고 문자열을 Uint8Array로 디코딩합니다.

const base64 = {
    decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
    encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
};

Node.js의 경우 다음을 사용하여 문자열, 버퍼 또는 Uint8Array를 문자열로 인코딩하고 문자열, 버퍼 또는 Uint8Array에서 버퍼로 디코딩 할 수 있습니다.

const base64 = {
    decode: s => Buffer.from(s, 'base64'),
    encode: b => Buffer.from(b).toString('base64')
};

13

Base64로 인코딩 된 문자열 URL을 친숙하게 만들려면 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/


9
나는 encodeURIComponent개발자의 노력을 덜 들이고 사용하면 우수한 결과를 얻을 수 있다고 겸손히 제안합니다 .
Pablo Fernandez

11
encodeURIComponent는 base64로 인코딩 된 문자열의 길이를 변경하고 URL에서 base64를 사용할 때 '-'및 '_'를 '+'로 바꾸고 '/'를 표준 방식으로 사용합니다 (예 : docs.python.org/library/base64.html#base64 .urlsafe_b64encode ). 화 내지 않아도됩니다.
natevw


12

나는 손으로 다시 쓴 한 이러한 인코딩 및 크로스 플랫폼 / 브라우저 호환성도 실제 개인 범위 지정에 모듈 형식으로 16 진수 하나를 제외하고 방법을 디코딩하고, 사용 btoa및 것은 atob그들이 속도로 인해 존재가 아닌 경우에 활용 자체 인코딩 :

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

용법:

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

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

12

이 질문과 답변은 올바른 방향을 제시했습니다.
특히 유니 코드 atob과 btoa는 "바닐라"를 사용할 수 없으며 요즘에는 모든 것이 유니 코드입니다 ..

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"

이러한 함수는 btoa 및 atob이 인터프리터 외부에서 실행되므로 사용자 정의 Javascript 함수를 사용하여 원시 base64 디코딩과 비교하여 번개를 빠르게 수행합니다.

오래된 IE와 오래된 휴대 전화 (예 : iphone 3?)를 무시할 수 있다면 좋은 해결책입니다.


10

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
}  

id로 이미지의 base64를 얻으려면 :

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

여기에


네, var img = new Image (); img.src = "../images/myPic.png";
pdschuller

7

현재 사용중인 window.atob+에 대해 축소 된 폴리 필을 제공 window.btoa합니다.

(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

모범 사례와 패턴을 사용하여 JavaScript로 구현 된 표준 및 보안 암호화 알고리즘을위한 가장 인기있는 라이브러리 인 CryptoJS 의 bas64 인코딩 / 디코딩 방법을 사용하고 싶습니다 .


6

다음은 @ user850789의 AngularJS 팩토리 버전입니다.

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

6

내 프로젝트의 base64로 UTF-8 문자열을 인코딩해야했습니다. 여기에있는 대부분의 답변은 UTF-8로 변환 할 때 UTF-16 대리 쌍을 올바르게 처리하지 못하는 것 같습니다. 따라서 완료를 위해 솔루션을 게시 할 것입니다.

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

내 프로젝트의 경우 여전히 IE7을 지원하고 큰 입력을 사용하여 인코딩해야합니다.

Joe Dyndale이 제안한 코드와 Marius가 제안한 코드를 기반으로 문자열 대신 배열로 결과를 구성하여 IE7의 성능을 향상시킬 수 있습니다.

다음은 encode의 예입니다.

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

5

조금 더 많은 작업을 수행하는 동안 고성능 기본 솔루션을 원한다면 사용할 수있는 HTML5 기능이 있습니다.

데이터를로 가져올 수 있으면 FileReader.readAsDataURL () 함수를 Blob사용하여 URL 을 가져 와서 앞쪽을 잘라 base64 데이터를 얻을 수 있습니다.data://

URL의 +문자가 이스케이프 인지 아닌지 확실하지 않기 때문에 데이터를 data://URL 디코딩하려면 추가 처리를 수행해야 할 수도 있지만, 이는 사소한 것입니다.


5

dojo를 사용하는 경우 base64로 인코딩하거나 디코딩하는 직접적인 방법을 제공합니다.

이 시도:-

dojox.encoding.base64를 사용하여 바이트 배열을 인코딩하려면 다음을 수행하십시오.

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

base64로 인코딩 된 문자열을 디코딩하려면

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

3

당신은 사용할 수 있습니다 window.btoawindow.atob...

const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
const decoded = window.atob(encoded); // decode the string

아마도 MDN 의 방식을 사용하면 최선을 다할 수 있습니다 ... 또한 유니 코드를 받아들이는 것 ... 다음 두 가지 간단한 기능을 사용하십시오.

// ucs-2 string to base64 encoded ascii
function utoa(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}
// base64 encoded ascii to ucs-2 string
function atou(str) {
    return decodeURIComponent(escape(window.atob(str)));
}
// Usage:
utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"

utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"

3

다음은 내장 된 함수 및 JS 의 라이브 데모 입니다 .atob()btoa()

<!DOCTYPE html>
<html>
  <head>
    <style>
      textarea{
        width:30%;
        height:100px;
      }
    </style>
    <script>
      // encode string to base64
      function encode()
      {
        var txt = document.getElementById("txt1").value;
        var result = btoa(txt);
        document.getElementById("txt2").value = result;
      }
      // decode base64 back to original string
      function decode()
      {
        var txt = document.getElementById("txt3").value;
        var result = atob(txt);
        document.getElementById("txt4").value = result;
      }
    </script>
  </head>
  <body>
    <div>
      <textarea id="txt1">Some text to decode
      </textarea>
    </div>
    <div>
      <input type="button" id="btnencode" value="Encode" onClick="encode()"/>
    </div>
    <div>
      <textarea id="txt2">
      </textarea>
    </div>
    <br/>
    <div>
      <textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
      </textarea>
    </div>
    <div>
      <input type="button" id="btndecode" value="Decode" onClick="decode()"/>
    </div>
    <div>
      <textarea id="txt4">
      </textarea>
    </div>
  </body>
</html>

2

js-base64 라이브러리를 다음과 같이 사용하십시오.

btoa ()는 이모티콘과 작동하지 않습니다

var str = "I was funny 😂";
console.log("Original string:", str);

var encodedStr = Base64.encode(str)
console.log("Encoded string:", encodedStr);

var decodedStr = Base64.decode(encodedStr)
console.log("Decoded string:", decodedStr);
<script src="https://cdn.jsdelivr.net/npm/js-base64@2.5.2/base64.min.js"></script>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.