বেস 64-কে ডিকোড করতে জাভাস্ক্রিপ্টের অ্যাটব ব্যবহার করে utf-8 স্ট্রিং সঠিকভাবে ডিকোড হয় না


106

আমি window.atob()একটি বেস 64-এনকোডযুক্ত স্ট্রিং (বিশেষত গিটহাব এপিআই থেকে বেস 64-এনকোডযুক্ত সামগ্রী) ডিকোড করতে জাভাস্ক্রিপ্ট ফাংশনটি ব্যবহার করছি । সমস্যা হ'ল আমি এএসসিআইআই-এনকোডেড অক্ষরগুলি ফিরে পাচ্ছি ( â¢পরিবর্তে এর মতো )। আমি কীভাবে আগত বেস 64-এনকোড স্ট্রিমটি সঠিকভাবে পরিচালনা করতে পারি যাতে এটি utf-8 হিসাবে ডিকোড হয়?


3
আপনি যে এমডিএন পৃষ্ঠাটি যুক্ত করেছেন তাতে একটি অনুচ্ছেদ রয়েছে যা "ইউনিকোড বা ইউটিএফ -8 স্ট্রিং ব্যবহারের জন্য" বাক্যাংশ দিয়ে শুরু হবে।
পয়েন্টি

1
আপনি নোডে আছেন? এর চেয়ে আরও ভাল সমাধান রয়েছেatob
বার্গি

উত্তর:


268

মজিলার এমডিএন ডক্স সম্পর্কে একটি দুর্দান্ত নিবন্ধ রয়েছে যা এই সমস্যাটি ঠিক বর্ণনা করে:

"ইউনিকোড সমস্যা" যেহেতু DOMStringগুলি 16-বিট-এনকোডেড স্ট্রিং, তাই window.btoaইউনিকোড স্ট্রিংয়ে কল করা বেশিরভাগ ব্রাউজারে Character Out Of Range exceptionযদি কোনও অক্ষর 8-বিট বাইট (0x00 ~ 0xFF) এর সীমা ছাড়িয়ে যায় তবে তার কারণ হতে পারে । এই সমস্যাটি সমাধানের জন্য দুটি সম্ভাব্য পদ্ধতি রয়েছে:

  • প্রথমটি হ'ল পুরো স্ট্রিংটি (ইউটিএফ -8 সহ, দেখুন encodeURIComponent) এবং তারপরে এনকোড করা;
  • দ্বিতীয়টি হ'ল UTF-16 DOMStringকে অক্ষরের UTF-8 অ্যারে রূপান্তর করতে হবে এবং তারপরে এটিকে এনকোড করা হবে।

পূর্ববর্তী সমাধানগুলির জন্য একটি নোট: এমডিএন নিবন্ধটি মূলত ব্যতিক্রমী সমস্যাটি ব্যবহার করার unescapeএবং escapeসমাধান করার পরামর্শ দিয়েছিল Character Out Of Range, তবে সেগুলি অবহেলা করা হয়েছে। এখানে অন্যান্য বেশ কয়েকটি উত্তরের সঙ্গে এই সমস্যা এড়ানোর কাজ পরামর্শ দিয়েছেন decodeURIComponentএবং encodeURIComponent, এই অবিশ্বস্ত এবং অনির্দেশ্য হতে প্রমাণিত হয়েছে। এই উত্তরের সর্বাধিক সাম্প্রতিক আপডেটটি গতি উন্নত করতে এবং কোডকে আধুনিকীকরণ করতে আধুনিক জাভাস্ক্রিপ্ট ফাংশন ব্যবহার করে।

আপনি যদি কিছু সময় নিজেকে বাঁচানোর চেষ্টা করছেন তবে আপনি একটি গ্রন্থাগার ব্যবহারের বিষয়টি বিবেচনা করতে পারেন:

ইউটিএফ 8 ⇢ বেস 64 এনকোডিং

function b64EncodeUnicode(str) {
    // first we use encodeURIComponent to get percent-encoded UTF-8,
    // then we convert the percent encodings into raw bytes which
    // can be fed into btoa.
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function toSolidBytes(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}

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

বেস 64 ⇢ ইউটিএফ 8 ডিকোডিং

function b64DecodeUnicode(str) {
    // Going backwards: from bytestream, to percent-encoding, to original string.
    return decodeURIComponent(atob(str).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

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

2018-এর প্রাক সমাধান (কার্যকরী, এবং সম্ভবত পুরানো ব্রাউজারগুলির পক্ষে আরও ভাল সমর্থন, আপ টু ডেট নয়)

এমডিএন থেকে সরাসরি বর্তমান সুপারিশটি হ'ল, এমএ-মাদিনের মাধ্যমে কিছু অতিরিক্ত টাইপস্ক্রিপ্টের সামঞ্জস্যতা:

// Encoding UTF8 ⇢ base64

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

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

// Decoding base64 ⇢ UTF8

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"

আসল সমাধান (অবনমিত)

এটি ব্যবহৃত escapeএবং unescape(যা এখন অবহেলিত, যদিও এটি এখনও সমস্ত আধুনিক ব্রাউজারে কাজ করে):

function utf8_to_b64( str ) {
    return window.btoa(unescape(encodeURIComponent( str )));
}

function b64_to_utf8( str ) {
    return decodeURIComponent(escape(window.atob( str )));
}

// Usage:
utf8_to_b64('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"

এবং একটি শেষ জিনিস: গিটহাব এপিআই কল করার সময় আমি প্রথম এই সমস্যার মুখোমুখি হয়েছি। এটিকে (মোবাইল) সাফারিটিতে সঠিকভাবে কাজ করার জন্য, উত্সটি ডিকোড করার আগেই আমাকে বেস 64 উত্স থেকে সমস্ত সাদা স্থানটি ছিনিয়ে নিতে হয়েছিল। এটি 2017 সালে এখনও প্রাসঙ্গিক কিনা, আমি জানি না:

function b64_to_utf8( str ) {
    str = str.replace(/\s/g, '');    
    return decodeURIComponent(escape(window.atob( str )));
}

1
w3schools.com/jsref/jsref_unescape.asp "ইউনেস্কেপ () ফাংশনটি জাভাস্ক্রিপ্ট সংস্করণ 1.5 তে অবহেলা করা হয়েছিল। পরিবর্তে ডিকোডুরি () বা ডিকোডেরিউআরকিউম্পোনেন্ট () ব্যবহার করুন" "
টেড হানসেন

1
আপনি আমার দিনগুলি বাঁচিয়েছেন, ভাই
মিঃ নিও

2
আপডেট করুন: সমাধান # 1 MDN এর "ইউনিকোড সমস্যা" নির্দিষ্ট করা হয়েছিল, b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU=');এখন সঠিকভাবে আউটপুট "✓ a la মোড"
weeix

2
ডিকোড করার আরেকটি উপায় decodeURIComponent(atob('4pyTIMOgIGxhIG1vZGU=').split('').map(x => '%' + x.charCodeAt(0).toString(16)).join('')) হ'ল সর্বাধিক পারফরম্যান্ট কোড নয়, তবে এটি এটি।
daniel.gindi

2
return String.fromCharCode(parseInt(p1, 16));টাইপস্ক্রিপ্ট সামঞ্জস্য আছে।
মার্টিন স্নাইডার

20

দ্রব্য পরিবর্তন. পালাবার / unescape পদ্ধতি অবচিত হয়েছে।

বেস 64-এনকোড করার আগে আপনি ইউআরআই স্ট্রিংটিকে এনকোড করতে পারেন। মনে রাখবেন যে এটি বেস 64-এনকোডেড ইউটিএফ 8 তৈরি করে না, বরং বেস 64-এনকোডেড ইউআরএল-এনকোডড ডেটা তৈরি করে। উভয় পক্ষকে অবশ্যই একই এনকোডিংয়ের বিষয়ে একমত হতে হবে।

এখানে কাজের উদাহরণ দেখুন: http://codepen.io/anon/pen/PZgbPW

// encode string
var base64 = window.btoa(encodeURIComponent('€ 你好 æøåÆØÅ'));
// decode string
var str = decodeURIComponent(window.atob(tmp));
// str is now === '€ 你好 æøåÆØÅ'

ওপির সমস্যার জন্য তৃতীয় পক্ষের লাইব্রেরি যেমন js-base64 এর সমস্যার সমাধান করা উচিত।


1
আমি উল্লেখ করতে চাই যে আপনি ইনপুট স্ট্রিংয়ের বেস 64 তৈরি করছেন না, তবে তার এনকোডযুক্ত উপাদানটি। সুতরাং যদি আপনি এটিকে প্রেরণ করেন তবে অন্য পক্ষ এটিকে "বেস 64" হিসাবে ডিকোড করতে এবং আসল স্ট্রিংটি পেতে পারে না
রিকার্ডো গাল্লি

3
আপনি সঠিক, আমি এটি উল্লেখ করতে পাঠ্য আপডেট করেছি। ধন্যবাদ। বিকল্পটি নিজেরাই বেস 64৪ বাস্তবায়ন করে তৃতীয় পক্ষের লাইব্রেরি (যেমন js-base64) ব্যবহার করে বা "ত্রুটি: 'উইন্ডো'তে' btoa 'কার্যকর করতে ব্যর্থ হয়েছে: এনকোড করা স্ট্রিংটিতে ল্যাটিন 1 ব্যাপ্তির বাইরে অক্ষর রয়েছে। "
টেড হানসেন

14

স্ট্রিংকে বাইট হিসাবে চিকিত্সা করা যদি আপনার জিনিস হয় তবে আপনি নিম্নলিখিত ফাংশনগুলি ব্যবহার করতে পারেন

function u_atob(ascii) {
    return Uint8Array.from(atob(ascii), c => c.charCodeAt(0));
}

function u_btoa(buffer) {
    var binary = [];
    var bytes = new Uint8Array(buffer);
    for (var i = 0, il = bytes.byteLength; i < il; i++) {
        binary.push(String.fromCharCode(bytes[i]));
    }
    return btoa(binary.join(''));
}


// example, it works also with astral plane characters such as '𝒞'
var encodedString = new TextEncoder().encode('✓');
var base64String = u_btoa(encodedString);
console.log('✓' === new TextDecoder().decode(u_atob(base64String)))

1
ধন্যবাদ। আপনার উত্তরটি আমাকে এই কাজ করতে সহায়তা করার ক্ষেত্রে গুরুত্বপূর্ণ ছিল, যা আমাকে একাধিক দিন ধরে বেশ কয়েক ঘন্টা সময় নিয়েছিল। +1 টি। stackoverflow.com/a/51814273/470749
রায়ান

অনেক দ্রুত এবং আরও ক্রস ব্রাউজার সমাধানের জন্য (তবে মূলত একই আউটপুট), দয়া করে দেখুন stackoverflow.com/a/53433503/5601591
জ্যাক গিফিন

u_atob এবং u_btoa IE10 (2012) থেকে প্রতিটি ব্রাউজারে উপলব্ধ ফাংশন ব্যবহার করে, আমার কাছে দৃ looks় মনে হয় (আপনি যদি টেক্সটইনকোডারটি উল্লেখ করেন তবে এটি কেবল একটি উদাহরণ)
রিকার্ডো গ্যালি

4

মজিলা বিকাশ সংস্থানগুলিতে বর্ণিত হিসাবে এখানে 2018 আপডেট সমাধান রয়েছে

ইউনিকোড থেকে বি 64 তে প্রবেশ করতে

function b64EncodeUnicode(str) {
    // first we use encodeURIComponent to get percent-encoded UTF-8,
    // then we convert the percent encodings into raw bytes which
    // can be fed into btoa.
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function toSolidBytes(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}

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

ইউনিকোডে বি 64 থেকে ছাড়ার জন্য

function b64DecodeUnicode(str) {
    // Going backwards: from bytestream, to percent-encoding, to original string.
    return decodeURIComponent(atob(str).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

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

3

আমি ধরে নেব যে কেউ এমন একটি সমাধান চান যা ব্যাপকভাবে ব্যবহারযোগ্য বেস 64 ইউআরআই উত্পাদন করে। অনুগ্রহ data:text/plain;charset=utf-8;base64,4pi44pi54pi64pi74pi84pi+4pi/করে দেখতে একটি দর্শন দেখুন (ডেটা ইউরি অনুলিপি করুন, একটি নতুন ট্যাব খুলুন, তথ্য বারে ইউআরআই তথ্য পেস্ট করুন, তারপরে পৃষ্ঠায় যাওয়ার জন্য এন্টার টিপুন)। এই ইউআরআই বেস 64-এনকোডড থাকা সত্ত্বেও, ব্রাউজারটি এখনও হাই কোড পয়েন্টগুলি সনাক্ত করতে এবং সেগুলি সঠিকভাবে ডিকোড করতে সক্ষম। মিনিফাইড এনকোডার + ডিকোডারটি 1058 বাইট (+ জিজিপ → 589 বাইট)

!function(e){"use strict";function h(b){var a=b.charCodeAt(0);if(55296<=a&&56319>=a)if(b=b.charCodeAt(1),b===b&&56320<=b&&57343>=b){if(a=1024*(a-55296)+b-56320+65536,65535<a)return d(240|a>>>18,128|a>>>12&63,128|a>>>6&63,128|a&63)}else return d(239,191,189);return 127>=a?inputString:2047>=a?d(192|a>>>6,128|a&63):d(224|a>>>12,128|a>>>6&63,128|a&63)}function k(b){var a=b.charCodeAt(0)<<24,f=l(~a),c=0,e=b.length,g="";if(5>f&&e>=f){a=a<<f>>>24+f;for(c=1;c<f;++c)a=a<<6|b.charCodeAt(c)&63;65535>=a?g+=d(a):1114111>=a?(a-=65536,g+=d((a>>10)+55296,(a&1023)+56320)):c=0}for(;c<e;++c)g+="\ufffd";return g}var m=Math.log,n=Math.LN2,l=Math.clz32||function(b){return 31-m(b>>>0)/n|0},d=String.fromCharCode,p=atob,q=btoa;e.btoaUTF8=function(b,a){return q((a?"\u00ef\u00bb\u00bf":"")+b.replace(/[\x80-\uD7ff\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g,h))};e.atobUTF8=function(b,a){a||"\u00ef\u00bb\u00bf"!==b.substring(0,3)||(b=b.substring(3));return p(b).replace(/[\xc0-\xff][\x80-\xbf]*/g,k)}}(""+void 0==typeof global?""+void 0==typeof self?this:self:global)

নীচে উত্স কোডটি এটি তৈরি করতে ব্যবহৃত হয়।

var fromCharCode = String.fromCharCode;
var btoaUTF8 = (function(btoa, replacer){"use strict";
    return function(inputString, BOMit){
        return btoa((BOMit ? "\xEF\xBB\xBF" : "") + inputString.replace(
            /[\x80-\uD7ff\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g, replacer
        ));
    }
})(btoa, function(nonAsciiChars){"use strict";
    // make the UTF string into a binary UTF-8 encoded string
    var point = nonAsciiChars.charCodeAt(0);
    if (point >= 0xD800 && point <= 0xDBFF) {
        var nextcode = nonAsciiChars.charCodeAt(1);
        if (nextcode !== nextcode) // NaN because string is 1 code point long
            return fromCharCode(0xef/*11101111*/, 0xbf/*10111111*/, 0xbd/*10111101*/);
        // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
        if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) {
            point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000;
            if (point > 0xffff)
                return fromCharCode(
                    (0x1e/*0b11110*/<<3) | (point>>>18),
                    (0x2/*0b10*/<<6) | ((point>>>12)&0x3f/*0b00111111*/),
                    (0x2/*0b10*/<<6) | ((point>>>6)&0x3f/*0b00111111*/),
                    (0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/)
                );
        } else return fromCharCode(0xef, 0xbf, 0xbd);
    }
    if (point <= 0x007f) return nonAsciiChars;
    else if (point <= 0x07ff) {
        return fromCharCode((0x6<<5)|(point>>>6), (0x2<<6)|(point&0x3f));
    } else return fromCharCode(
        (0xe/*0b1110*/<<4) | (point>>>12),
        (0x2/*0b10*/<<6) | ((point>>>6)&0x3f/*0b00111111*/),
        (0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/)
    );
});

তারপরে, বেস 64৪ ডেটা ডিকোড করতে, HTTP ডেটা ইউআরআই হিসাবে ডেটা পান বা নীচের ফাংশনটি ব্যবহার করুন।

var clz32 = Math.clz32 || (function(log, LN2){"use strict";
    return function(x) {return 31 - log(x >>> 0) / LN2 | 0};
})(Math.log, Math.LN2);
var fromCharCode = String.fromCharCode;
var atobUTF8 = (function(atob, replacer){"use strict";
    return function(inputString, keepBOM){
        inputString = atob(inputString);
        if (!keepBOM && inputString.substring(0,3) === "\xEF\xBB\xBF")
            inputString = inputString.substring(3); // eradicate UTF-8 BOM
        // 0xc0 => 0b11000000; 0xff => 0b11111111; 0xc0-0xff => 0b11xxxxxx
        // 0x80 => 0b10000000; 0xbf => 0b10111111; 0x80-0xbf => 0b10xxxxxx
        return inputString.replace(/[\xc0-\xff][\x80-\xbf]*/g, replacer);
    }
})(atob, function(encoded){"use strict";
    var codePoint = encoded.charCodeAt(0) << 24;
    var leadingOnes = clz32(~codePoint);
    var endPos = 0, stringLen = encoded.length;
    var result = "";
    if (leadingOnes < 5 && stringLen >= leadingOnes) {
        codePoint = (codePoint<<leadingOnes)>>>(24+leadingOnes);
        for (endPos = 1; endPos < leadingOnes; ++endPos)
            codePoint = (codePoint<<6) | (encoded.charCodeAt(endPos)&0x3f/*0b00111111*/);
        if (codePoint <= 0xFFFF) { // BMP code point
          result += fromCharCode(codePoint);
        } else if (codePoint <= 0x10FFFF) {
          // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
          codePoint -= 0x10000;
          result += fromCharCode(
            (codePoint >> 10) + 0xD800,  // highSurrogate
            (codePoint & 0x3ff) + 0xDC00 // lowSurrogate
          );
        } else endPos = 0; // to fill it in with INVALIDs
    }
    for (; endPos < stringLen; ++endPos) result += "\ufffd"; // replacement character
    return result;
});

আরও স্ট্যান্ডার্ড হওয়ার সুবিধা হ'ল এই এনকোডার এবং এই ডিকোডারটি আরও ব্যাপকভাবে প্রযোজ্য কারণ এগুলি কার্যকরভাবে ইউআরএল হিসাবে ব্যবহার করা যেতে পারে যা সঠিকভাবে প্রদর্শিত হয়। কর।

(function(window){
    "use strict";
    var sourceEle = document.getElementById("source");
    var urlBarEle = document.getElementById("urlBar");
    var mainFrameEle = document.getElementById("mainframe");
    var gotoButton = document.getElementById("gotoButton");
    var parseInt = window.parseInt;
    var fromCodePoint = String.fromCodePoint;
    var parse = JSON.parse;
    
    function unescape(str){
        return str.replace(/\\u[\da-f]{0,4}|\\x[\da-f]{0,2}|\\u{[^}]*}|\\[bfnrtv"'\\]|\\0[0-7]{1,3}|\\\d{1,3}/g, function(match){
          try{
            if (match.startsWith("\\u{"))
              return fromCodePoint(parseInt(match.slice(2,-1),16));
            if (match.startsWith("\\u") || match.startsWith("\\x"))
              return fromCodePoint(parseInt(match.substring(2),16));
            if (match.startsWith("\\0") && match.length > 2)
              return fromCodePoint(parseInt(match.substring(2),8));
            if (/^\\\d/.test(match)) return fromCodePoint(+match.slice(1));
          }catch(e){return "\ufffd".repeat(match.length)}
          return parse('"' + match + '"');
        });
    }
    
    function whenChange(){
      try{ urlBarEle.value = "data:text/plain;charset=UTF-8;base64," + btoaUTF8(unescape(sourceEle.value), true);
      } finally{ gotoURL(); }
    }
    sourceEle.addEventListener("change",whenChange,{passive:1});
    sourceEle.addEventListener("input",whenChange,{passive:1});
    
    // IFrame Setup:
    function gotoURL(){mainFrameEle.src = urlBarEle.value}
    gotoButton.addEventListener("click", gotoURL, {passive: 1});
    function urlChanged(){urlBarEle.value = mainFrameEle.src}
    mainFrameEle.addEventListener("load", urlChanged, {passive: 1});
    urlBarEle.addEventListener("keypress", function(evt){
      if (evt.key === "enter") evt.preventDefault(), urlChanged();
    }, {passive: 1});
    
        
    var fromCharCode = String.fromCharCode;
    var btoaUTF8 = (function(btoa, replacer){
		    "use strict";
        return function(inputString, BOMit){
        	return btoa((BOMit?"\xEF\xBB\xBF":"") + inputString.replace(
        		/[\x80-\uD7ff\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g, replacer
    		));
    	}
    })(btoa, function(nonAsciiChars){
		"use strict";
    	// make the UTF string into a binary UTF-8 encoded string
    	var point = nonAsciiChars.charCodeAt(0);
    	if (point >= 0xD800 && point <= 0xDBFF) {
    		var nextcode = nonAsciiChars.charCodeAt(1);
    		if (nextcode !== nextcode) { // NaN because string is 1code point long
    			return fromCharCode(0xef/*11101111*/, 0xbf/*10111111*/, 0xbd/*10111101*/);
    		}
    		// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
    		if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) {
    			point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000;
    			if (point > 0xffff) {
    				return fromCharCode(
    					(0x1e/*0b11110*/<<3) | (point>>>18),
    					(0x2/*0b10*/<<6) | ((point>>>12)&0x3f/*0b00111111*/),
    					(0x2/*0b10*/<<6) | ((point>>>6)&0x3f/*0b00111111*/),
    					(0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/)
    				);
    			}
    		} else {
    			return fromCharCode(0xef, 0xbf, 0xbd);
    		}
    	}
    	if (point <= 0x007f) { return inputString; }
    	else if (point <= 0x07ff) {
    		return fromCharCode((0x6<<5)|(point>>>6), (0x2<<6)|(point&0x3f/*00111111*/));
    	} else {
    		return fromCharCode(
    			(0xe/*0b1110*/<<4) | (point>>>12),
    			(0x2/*0b10*/<<6) | ((point>>>6)&0x3f/*0b00111111*/),
    			(0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/)
    		);
    	}
    });
    setTimeout(whenChange, 0);
})(window);
img:active{opacity:0.8}
<center>
<textarea id="source" style="width:66.7vw">Hello \u1234 W\186\0256ld!
Enter text into the top box. Then the URL will update automatically.
</textarea><br />
<div style="width:66.7vw;display:inline-block;height:calc(25vw + 1em + 6px);border:2px solid;text-align:left;line-height:1em">
<input id="urlBar" style="width:calc(100% - 1em - 13px)" /><img id="gotoButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAeCAMAAADqx5XUAAAAclBMVEX///9NczZ8e32ko6fDxsU/fBoSQgdFtwA5pAHVxt+7vLzq5ex23y4SXABLiiTm0+/c2N6DhoQ6WSxSyweVlZVvdG/Uz9aF5kYlbwElkwAggACxs7Jl3hX07/cQbQCar5SU9lRntEWGum+C9zIDHwCGnH5IvZAOAAABmUlEQVQoz7WS25acIBBFkRLkIgKKtOCttbv//xdDmTGZzHv2S63ltuBQQP4rdRiRUP8UK4wh6nVddQwj/NtDQTvac8577zTQb72zj65/876qqt7wykU6/1U6vFEgjE1mt/5LRqrpu7oVsn0sjZejMfxR3W/yLikqAFcUx93YxLmZGOtElmEu6Ufd9xV3ZDTGcEvGLbMk0mHHlUSvS5svCwS+hVL8loQQyfpI1Ay8RF/xlNxcsTchGjGDIuBG3Ik7TMyNxn8m0TSnBAK6Z8UZfp3IbAonmJvmsEACum6aNv7B0CnvpezDcNhw9XWsuAr7qnRg6dABmeM4dTgn/DZdXWs3LMspZ1KDMt1kcPJ6S1icWNp2qaEmjq6myx7jbQK3VKItLJaW5FR+cuYlRhYNKzGa9vF4vM5roLW3OSVjkmiGJrPhUq301/16pVKZRGFYWjTP50spTxBN5Z4EKnSonruk+n4tUokv1aJSEl/MLZU90S3L6/U6o0J142iQVp3HcZxKSo8LfkNRCtJaKYFSRX7iaoAAUDty8wvWYR6HJEepdwAAAABJRU5ErkJggg==" style="width:calc(1em + 4px);line-height:1em;vertical-align:-40%;cursor:pointer" />
<iframe id="mainframe" style="width:66.7vw;height:25vw" frameBorder="0"></iframe>
</div>
</center>

খুব মানসম্পন্ন হওয়ার পাশাপাশি উপরের কোড স্নিপেটগুলিও খুব দ্রুত। পর পর পরোক্ষ একটি পরোক্ষ শৃঙ্খলার পরিবর্তে যেখানে বিভিন্ন রূপের মধ্যে ডেটা কয়েকবার রূপান্তর করতে হয় (যেমন রিকার্ডো গালির প্রতিক্রিয়াতে), উপরের কোড স্নিপেট পারফরম্যান্টভাবে সম্ভব হিসাবে সরাসরি। এটি String.prototype.replaceএনকোডিং করার সময় ডেটা প্রসেস করতে শুধুমাত্র একটি সাধারণ দ্রুত কল ব্যবহার করে এবং ডিকোডিংয়ের সময় কেবলমাত্র ডেটা ডিকোড করতে। আর একটি প্লাস হ'ল (বিশেষত বড় স্ট্রিংগুলির জন্য), String.prototype.replaceব্রাউজারটি স্বয়ংক্রিয়ভাবে স্ট্রিংটির আকার পরিবর্তন করার অন্তর্নিহিত মেমরি পরিচালনা করতে সক্ষম করে, বিশেষত ক্রোম এবং ফায়ারফক্সের মতো চিরসবুজ ব্রাউজারগুলিতে একটি তাত্পর্যপূর্ণ পারফরম্যান্স উত্সাহ দেয় যা ভারীভাবে অনুকূল করে তোলেString.prototype.replace। শেষ অবধি, কেকের আইসিংটি হ'ল ল্যাটিন স্ক্রিপ্ট এক্সক্লুসিভ ব্যবহারকারীদের জন্য, 0x7f এর উপরে কোনও কোড পয়েন্ট না থাকা স্ট্রিংগুলি প্রক্রিয়া করার জন্য অতিরিক্ত দ্রুত হয় কারণ স্ট্রিংটি প্রতিস্থাপন অ্যালগরিদম দ্বারা অযৌক্তিকর থেকে যায়।

আমি এই সমাধানের জন্য https://github.com/anonyco/BestBase64EncoderDecoder/ এ গিথুব সংগ্রহস্থল তৈরি করেছি


"ব্রাউজার দ্বারা ব্যাখ্যাযোগ্য" "ব্যবহারকারীর দ্বারা নির্মিত উপায়ে" "বনাম" বলতে কী বোঝাতে চেয়েছেন তা বোঝাতে পারেন? এই সমাধানটির ওপরে কী কী মূল্য যুক্ত হবে, বলুন, মজিলা কী প্রস্তাব দেয়?
ব্র্যান্ডস্ক্রিপ্ট

@ ব্র্যান্ডসস্ক্রিপ্ট মজিলা এমডিএন থেকে আলাদা is এমডিএন ব্যবহারকারী-তৈরি সামগ্রী। MDN- এ থাকা পৃষ্ঠাটি যা আপনার সমাধানটির প্রস্তাব দেয় সেটি ব্যবহারকারী দ্বারা তৈরি সামগ্রী ছিল, ব্রাউজার বিক্রেতার তৈরি সামগ্রী নয়।
জ্যাক গিফিন

আপনার সমাধান বিক্রেতা তৈরি করা হয়? আমি তাই চাই, আমি উত্সটিকে creditণ দেওয়ার পরামর্শ দিই। যদি তা না হয় তবে এটিও ব্যবহারকারী দ্বারা নির্মিত, এবং এমডিএন এর উত্তর থেকে আলাদা নয়?
ব্র্যান্ডস্ক্রিপ্ট

@ ব্র্যান্ডসস্ক্রিপ্ট ভাল পয়েন্ট। আপনি সঠিক. আমি সেই টুকরো টুকরো মুছে ফেলেছি। এছাড়াও, আমি যুক্ত করা ডেমো পরীক্ষা করে দেখুন।
জ্যাক গিফিন

3

সম্পূর্ণ নিবন্ধ যা আমার পক্ষে কাজ করে: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_ and_decoding

আমরা যে অংশটি ইউনিকোড / ইউটিএফ -8 থেকে এনকোড করেছি is

function utf8_to_b64( str ) {
   return window.btoa(unescape(encodeURIComponent( str )));
}

function b64_to_utf8( str ) {
   return decodeURIComponent(escape(window.atob( str )));
}

// Usage:
utf8_to_b64('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"

আজকাল এটি অন্যতম ব্যবহৃত পদ্ধতি।


এটি গৃহীত উত্তরের মতো একই লিঙ্ক।
ব্র্যান্ডস্ক্রিপ্ট

0

ছোট সংশোধন, আনস্কেপ এবং পলায়ন অবহেলিত, তাই:

function utf8_to_b64( str ) {
    return window.btoa(decodeURIComponent(encodeURIComponent(str)));
}

function b64_to_utf8( str ) {
     return decodeURIComponent(encodeURIComponent(window.atob(str)));
}


function b64_to_utf8( str ) {
    str = str.replace(/\s/g, '');    
    return decodeURIComponent(encodeURIComponent(window.atob(str)));
}

2
দেখে মনে হচ্ছে ডক লিঙ্কটি এখন এটির থেকে আলাদা, এটি পরিচালনা করার জন্য একটি রেইগেক্স সমাধানের পরামর্শ দেয়।
ব্র্যান্ডস্ক্রিপ্ট

2
এটি কাজ করবে না, কারণ encodeURIComponentএর বিপরীতটি decodeURIComponent, অর্থাত্ এটি রূপান্তরটিকে পূর্বাবস্থায় ফিরিয়ে আনবে। কী এবং এর সাথে কী ঘটছে তার দুর্দান্ত ব্যাখ্যার জন্য স্ট্যাকওভারফ্লো.com/ a/ 31412163/1534459 দেখুন । escapeunescape
বোডো

1
@ কানাআেরুস আমি আপনার মন্তব্য বুঝতে পারছি না? এস্কেপ এবং আনস্কেপকে অবমূল্যায়ন করা হয়েছে, আমি কেবল সেগুলি [ডিকোড | এনকোড] ইউআরিকম্পোম্পোনেন্ট ফাংশন দিয়ে সরিয়ে নিয়েছি :-) সবকিছু ঠিকঠাক কাজ করছে। প্রথমে প্রশ্নটি পড়ুন
ডার্কভেস

1
@ ডার্কভেস: encodeURIComponentইউনিকোড স্ট্রিং সঠিকভাবে (পুরো ব্যাপ্তি) হ্যান্ডেল করানোর কারণটি ব্যবহৃত হচ্ছে। সুতরাং যেমন window.btoa(decodeURIComponent(encodeURIComponent('€')))দেয় Error: String contains an invalid characterকারণ এটি একই window.btoa('€')এবং btoaএনকোড করতে পারে না
বোডো

2
@ ডার্কভেস: হ্যাঁ, এটা ঠিক। তবে আপনি এনকোডিউআরআইকিউম্পোনেন্ট এবং ডিকোডেরিউআইকিউম্পোনেন্ট সহ আনসকেপ দিয়ে পালাতে পারবেন না, কারণ এনকোড এবং পালানোর পদ্ধতিগুলি একই কাজ করে না। ডিকোড এবং আনসকেপ সহ একই। আমি মূলত একই ভুলটি করেছি, বিটিডব্লিউ। আপনার লক্ষ্য করা উচিত যে আপনি যদি একটি স্ট্রিং নেন তবে এটি ইউরিএনকোড করুন, তারপরে এটি ইউরিডেকোড করুন, আপনি একই স্ট্রিংটি ফিরে পেয়েছেন যা আপনি ইনপুট করেছিলেন। সুতরাং এটা করা বাজে কথা হবে। আপনি যখন এনকোডিউআরআইকিউম্পোন্টের সাথে এনকোডযুক্ত একটি স্ট্রিংটি অনস্কেপ করবেন তখন আপনি যে স্ট্রিংটি ইনপুট দিয়েছিলেন তা আর পাবেন না, তাই পলায়ন / আনস্কেপ দিয়ে এটি কাজ করে তবে আপনার সাথে নয়।
স্টিফান স্টেইগার

0

ব্রাউজারগুলির জন্য এখানে কিছু ভবিষ্যতের প্রুফ কোড রয়েছে যার অভাব হতে পারে escape/unescape()। মনে রাখবেন যে 9 বা তার বেশি atob/btoa()বয়সীরা সমর্থন করে না , সুতরাং তাদের জন্য আপনার কাস্টম বেস 64 ফাংশন ব্যবহার করা দরকার।

// Polyfill for escape/unescape
if( !window.unescape ){
    window.unescape = function( s ){
        return s.replace( /%([0-9A-F]{2})/g, function( m, p ) {
            return String.fromCharCode( '0x' + p );
        } );
    };
}
if( !window.escape ){
    window.escape = function( s ){
        var chr, hex, i = 0, l = s.length, out = '';
        for( ; i < l; i ++ ){
            chr = s.charAt( i );
            if( chr.search( /[A-Za-z0-9\@\*\_\+\-\.\/]/ ) > -1 ){
                out += chr; continue; }
            hex = s.charCodeAt( i ).toString( 16 );
            out += '%' + ( hex.length % 2 != 0 ? '0' : '' ) + hex;
        }
        return out;
    };
}

// Base64 encoding of UTF-8 strings
var utf8ToB64 = function( s ){
    return btoa( unescape( encodeURIComponent( s ) ) );
};
var b64ToUtf8 = function( s ){
    return decodeURIComponent( escape( atob( s ) ) );
};

ইউটিএফ -8 এনকোডিং এবং ডিকোডিংয়ের আরও বিশদ উদাহরণ এখানে পাওয়া যাবে: http://jsfiddle.net/47zwb41o/


-1

উপরের সমাধান সহ যদি এখনও সমস্যার মুখোমুখি হয় তবে নীচের হিসাবে চেষ্টা করুন, টিএস-এর জন্য পলায়ন সমর্থিত নয় এমন ক্ষেত্রে বিবেচনা করুন।

blob = new Blob(["\ufeff", csv_content]); // this will make symbols to appears in excel 

সিএসভি_ কনটেন্টের জন্য আপনি নীচের মত চেষ্টা করতে পারেন।

function b64DecodeUnicode(str: any) {        
        return decodeURIComponent(atob(str).split('').map((c: any) => {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.