ฉันมีสคริปต์ PHP ที่สามารถเข้ารหัสภาพ PNG เป็นสตริง Base64
ฉันต้องการทำสิ่งเดียวกันโดยใช้ JavaScript ฉันรู้วิธีเปิดไฟล์ แต่ฉันไม่แน่ใจว่าจะเข้ารหัสได้อย่างไร ฉันไม่คุ้นเคยกับการทำงานกับข้อมูลไบนารี
ฉันมีสคริปต์ PHP ที่สามารถเข้ารหัสภาพ PNG เป็นสตริง Base64
ฉันต้องการทำสิ่งเดียวกันโดยใช้ JavaScript ฉันรู้วิธีเปิดไฟล์ แต่ฉันไม่แน่ใจว่าจะเข้ารหัสได้อย่างไร ฉันไม่คุ้นเคยกับการทำงานกับข้อมูลไบนารี
คำตอบ:
คุณสามารถใช้btoa()
และatob()
เพื่อแปลงเป็นและจากการเข้ารหัส base64
ดูเหมือนจะมีความสับสนในความคิดเห็นเกี่ยวกับสิ่งที่ฟังก์ชั่นเหล่านี้ยอมรับ / ส่งคืนดังนั้น ...
btoa()
ยอมรับ“ สตริง” โดยที่ตัวละครแต่ละตัวแทนไบต์ 8 บิต - หากคุณผ่านสตริงที่มีตัวอักษรที่ไม่สามารถแสดงได้ใน 8 บิตมันอาจจะแตกได้ นี่ไม่ใช่ปัญหาหากคุณใช้สตริงเป็นอาร์เรย์ไบต์ แต่ถ้าคุณพยายามทำอย่างอื่นคุณจะต้องเข้ารหัสก่อน
atob()
ส่งกลับ“สตริง” ที่ตัวละครแต่ละตัวหมายถึงไบต์ 8 บิต - นั่นคือค่าของมันจะอยู่ระหว่างและ0
0xff
นี่ไม่ได้หมายความว่ามันเป็น ASCII - สมมุติว่าถ้าคุณใช้ฟังก์ชั่นนี้คุณคาดว่าจะทำงานกับข้อมูลไบนารีไม่ใช่ข้อความ
btoa(unescape(encodeURIComponent(str))))
ถ้า STR คือ UFT8
/**
*
* 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"จะเปิดตัวเลือกอื่น ๆ อีกมากมายด้านบนเป็นตัวเลือกแรก
string = string.replace(/\r\n/g,"\n");
คำสั่งที่น่าสงสัยในวิธีการเข้ารหัส utf8
string = string.replace(/\r\n/g,"\n");
ในตอนแรกฮ่า ๆ มันเหมือนกับ "โอ้ให้เข้ารหัสสตริงนี้ แต่ก่อนอื่นทำไมเราไม่เพียงแค่ทำให้การแบ่งบรรทัดทั้งหมดเป็นแบบปกติโดยไม่มีเหตุผลที่ดีเลย" ที่ควรถูกลบออกจากชั้นอย่างแน่นอนในทุกสถานการณ์
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
น่านค่าของมันจะยังคงใช้ในคำสั่ง ในเบราว์เซอร์ของฉันมันใช้งานได้ดีNaN>>4
เท่ากับ 0 แต่ฉันไม่รู้ว่าเบราว์เซอร์ทั้งหมดทำสิ่งนี้หรือไม่ ( NaN/16
เท่ากับ NaN)
// 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!"
นี่คือวิธีที่คุณเข้ารหัสข้อความปกติเป็น 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();
ในการเข้ารหัสอาร์เรย์ของไบต์โดยใช้ dojox.encoding.base64:
var str = dojox.encoding.base64.encode(myByteArray);
ในการถอดรหัสสตริงที่เข้ารหัสแบบ 64:
var bytes = dojox.encoding.base64.decode(str)
<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=');
}]);
รหัสของ 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;
}
}
คุณสามารถใช้btoa
(ไปยังฐาน 64) และatob
(จากฐาน -64)
สำหรับ IE 9 และด้านล่างให้ลองปลั๊กอินjquery-base64 :
$.base64.encode("this is a test");
$.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
base64.encode(...)
และbase64.decode(...)
... แนบไป jQuery เมื่อมีศูนย์การทำงานที่เฉพาะเจาะจง jQuery ทำให้รู้สึกไม่แน่นอน ...
จากความคิดเห็น (โดย 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 แต่ไม่ใช่สำหรับการเข้ารหัส / ถอดรหัส)
Buffer.from(b64data, 'base64').toString();
มีข้อบกพร่องสอง_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;
}
ฉัน +1 คำตอบของ Sunny แต่ฉันต้องการสนับสนุนการเปลี่ยนแปลงเล็กน้อยที่ฉันทำไว้สำหรับโครงการของฉันเองในกรณีที่ทุกคนควรพบว่ามีประโยชน์ โดยทั่วไปฉันเพิ่งทำความสะอาดรหัสต้นฉบับเล็กน้อยเพื่อ 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
};
}());
สำหรับเบราว์เซอร์ที่ใหม่กว่าในการเข้ารหัส 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')
};
ในการทำให้สตริง 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/
encodeURIComponent
อาจส่งผลให้เกิดผลลัพธ์ที่เหนือกว่าโดยใช้ความพยายามน้อยลงในส่วนของนักพัฒนาซอฟต์แวร์
โปรดทราบว่าสิ่งนี้ไม่เหมาะสำหรับสตริง Unicode ที่ไม่สมบูรณ์! ดูในส่วน Unicode ที่นี่
ไวยากรณ์สำหรับการเข้ารหัส
var encodedData = window.btoa(stringToEncode);
ไวยากรณ์สำหรับการถอดรหัส
var decodedData = window.atob(encodedData);
ฉันเขียนใหม่ด้วยมือวิธีการเข้ารหัสและถอดรหัสเหล่านี้ยกเว้นเลขฐานสิบหกเป็นรูปแบบโมดูลาร์สำหรับการทำงานร่วมกันข้ามแพลตฟอร์ม / เบราว์เซอร์และยังมีการกำหนดขอบเขตส่วนตัวที่แท้จริงและการใช้งานbtoa
และatob
หากมีอยู่เนื่องจากความเร็วแทนที่จะใช้ การเข้ารหัสของตัวเอง:
https://gist.github.com/Nijikokun/5192472
การใช้งาน:
base64.encode(/* String */);
base64.decode(/* String */);
utf8.encode(/* String */);
utf8.decode(/* String */);
คำถามนี้และคำตอบก็ชี้ให้ฉันเห็นทิศทางที่ถูกต้อง
โดยเฉพาะอย่างยิ่งกับ Unicode atob และ btoa ไม่สามารถใช้ "วานิลลา" และทุกวันนี้ทุกอย่างเป็น Unicode ..
โดยตรงจาก Mozilla สองฟังก์ชันที่ยอดเยี่ยมสำหรับจุดประสงค์นี้ (ทดสอบด้วย unicode และแท็ก 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"
ฟังก์ชั่นเหล่านี้จะทำงานเร็วกว่าฟ้าผ่าเมื่อเปรียบเทียบกับการถอดรหัสเบส 64 แบบดิบโดยใช้ฟังก์ชั่นจาวาสคริปต์ที่กำหนดเองเนื่องจากมีการดำเนินการ btoa และ atob นอกล่าม
หากคุณสามารถละเว้น IE เก่าและโทรศัพท์มือถือรุ่นเก่า (เช่น iphone 3 ได้) นี่ควรเป็นทางออกที่ดี
หากคุณต้องการเข้ารหัสออบเจ็กต์อิมเมจ 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));
}
เพิ่มเติมที่นี่
มีส่วนร่วมกับ polyfill ขนาดเล็กสำหรับ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})})();
นี่คือ 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;
});
ฉันต้องการการเข้ารหัสสตริง 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/ )
สำหรับโครงการของฉันฉันยังต้องสนับสนุน IE7 และทำงานกับอินพุตขนาดใหญ่เพื่อเข้ารหัส
ขึ้นอยู่กับรหัสที่เสนอโดย Joe Dyndale และตามที่แนะนำไว้ในข้อคิดเห็นโดย Marius เป็นไปได้ที่จะปรับปรุงประสิทธิภาพด้วย 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("");
};
ในขณะที่ทำงานได้อีกเล็กน้อยหากคุณต้องการโซลูชันเนทิฟประสิทธิภาพสูงมีฟังก์ชัน HTML5 บางอย่างที่คุณสามารถใช้ได้
หากคุณสามารถนำข้อมูลของคุณเข้าสู่ a Blob
คุณสามารถใช้ฟังก์ชันFileReader.readAsDataURL ()เพื่อรับdata://
URL และตัดส่วนที่อยู่ด้านหน้าออกเพื่อรับข้อมูล base64
คุณอาจต้องทำการประมวลผลต่อไปเพื่อทำการถอดรหัสข้อมูลเพราะฉันไม่แน่ใจว่า+
ตัวละครนั้นถูกหลบหนีหรือไม่สำหรับdata://
URL แต่สิ่งนี้น่าสนใจเล็กน้อย
ถ้าคุณใช้โดโจมันทำให้เราได้วิธีเข้ารหัสหรือถอดรหัสใน base64 โดยตรง
ลองนี้: -
ในการเข้ารหัสอาร์เรย์ของไบต์โดยใช้ dojox.encoding.base64:
var str = dojox.encoding.base64.encode(myByteArray);
ในการถอดรหัสสตริงที่เข้ารหัสแบบ 64:
var bytes = dojox.encoding.base64.decode(str);
คุณสามารถใช้window.btoa
และwindow.atob
...
const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
const decoded = window.atob(encoded); // decode the string
อาจใช้วิธีการที่MDNสามารถทำงานของคุณได้ดีที่สุด ... ยอมรับ unicode ... ด้วยฟังก์ชั่นง่าย ๆ สองอย่างนี้:
// 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!"
นี่คือการสาธิตสดของatob()
และbtoa()
JS ในตัวฟังก์ชั่น:
<!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>
ใช้ไลบรารี 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>