বেস 64 টি এনকোডড স্ট্রিংয়ে অ্যারেবফার


203

আমার ArrayBufferএকটি বেস 64৪ স্ট্রিংয়ে রূপান্তর করতে একটি দক্ষ (দেশীয় পড়ুন) উপায় প্রয়োজন যা একটি মাল্টিপার্ট পোস্টে ব্যবহার করা দরকার।

উত্তর:


221
function _arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}

তবে, অ-নেটিভ বাস্তবায়ন দ্রুত হয় যেমন https://gist.github.com/958841 দেখুন http://jsperf.com/encoding-xhr-image-data/6


10
আমি লিঙ্কটি থেকে অ দেশীয় বাস্তবায়ন চেষ্টা করেছি এবং 1 এম আকারের বাফারে রূপান্তর করতে 1 মিনিট এবং অর্ধেক সময় লেগেছিল যখন উপরের লুপ কোডটি কেবল 1 সেকেন্ড নিয়েছিল।
cshu

1
আমি এই পদ্ধতির সরলতা পছন্দ করি তবে সমস্ত স্ট্রিং সংমিশ্রণ ব্যয়বহুল হতে পারে। দেখে মনে হচ্ছে অক্ষরগুলির একটি অ্যারে তৈরি করা এবং join()সেগুলি শেষে ফায়ারফক্স, আইই এবং সাফারি (তবে ক্রোমের তুলনায়
JLRishe

আমি এই ফাংশনটি অ্যারে বাফারের জন্য বেস 64 তে রূপান্তর করতে ব্যবহার করছি তবে আমি অ্যারে বাফারটি ফিরে পেতে সক্ষম হই না। আমি এখানে একটি _base64ToArrayBuffer () ফাংশন কবিতা করেছি: কোড ारे.ইও / পিটি 4 পিবি তবে এটি আমাকে ত্রুটি দেয়:Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
বাউজাকুনাল

এটি এই জেএসজিপ কাজ করে না। আমি আরেকটি উপায় খুঁজে পাই github.com/michael/github/issues/137
রাউআর

1
আমি Angualrjs এবং webapi2 ব্যবহার করে 50mb পিডিএফ ফাইল আপলোড চেষ্টা করছি। আমি উপরের লাইন কোডটি ব্যবহার করছি, ফাইল আপলোড করার পরে পৃষ্ঠাটি ক্র্যাশ হয়ে ঝুলিয়ে দেওয়া হয়েছে। কোড লাইনের নীচে, আমি ব্যবহৃত হয়েছিল তবে ওয়েবপিপি পদ্ধতিতে নাল মান পাচ্ছিলাম। "var base64String = btoa (String.fromCharCode.apply (নাল, নতুন Uint8Array (অ্যারেবফার)));" দয়া করে কোনও ধারণা প্রস্তাব করুন ...
প্রভাকরণ এস

101

এটি আমার পক্ষে ভাল কাজ করে:

var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));

ES6-তে বাক্যবিন্যাসটি কিছুটা সহজ:

let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));

মন্তব্যে নির্দেশিত হিসাবে, এই পদ্ধতিটি ArrayBufferবড় হয়ে গেলে কিছু ব্রাউজারে একটি রানটাইম ত্রুটির কারণ হতে পারে । সঠিক আকার সীমা যে কোনও ক্ষেত্রে বাস্তবায়ন নির্ভর করে is


38
সংক্ষিপ্ততার জন্য আমি এই পদ্ধতিটি আরও ভাল পছন্দ করি তবে একটি "সর্বাধিক কল স্ট্যাকের আকার ত্রুটি ছাড়িয়ে গেছে" পেতে পারি। উপরে লুপ কৌশল প্রায় কাছাকাছি পায়।
জয়

13
আমি স্ট্যাক সাইজের ত্রুটিও পাচ্ছি, তাই আমি মবজের উত্তরটি ব্যবহার করেছি এবং এটি দুর্দান্ত কাজ করেছে।
ডেভিড জোন্স

12
এটি বড় বাফারগুলির জন্য কাজ করে না। এটিকে কাজ করতে সামান্য পরিবর্তন করুন:btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
laggingreflex

1
আমি Angualrjs এবং webapi2 ব্যবহার করে 50mb পিডিএফ ফাইল আপলোড চেষ্টা করছি। আমি উপরের লাইন কোডটি ব্যবহার করছি, ফাইল আপলোড করার পরে পৃষ্ঠাটি ক্র্যাশ হয়ে ঝুলিয়ে দেওয়া হয়েছে। কোড লাইনের নীচে, আমি ব্যবহৃত হয়েছিল তবে ওয়েবপিপি পদ্ধতিতে নাল মান পাচ্ছিলাম। "var base64String = btoa (String.fromCharCode.apply (নাল, নতুন Uint8Array (অ্যারেবফার)));" দয়া করে কোনও ধারণা প্রস্তাব করুন ...
প্রভাকরণ এস

2
@ কুজেল btoa0-255 কোডের পরিসরের অক্ষরের জন্য নিরাপদ, কারণ এখানে এটি রয়েছে (8 টি সম্পর্কে চিন্তা করুন Uint8Array)।
0

42

যাঁরা এটি সংক্ষিপ্ত পছন্দ করেন তাদের জন্য, এখানে এমন আরও একটি ব্যবহার রয়েছে Array.reduceযা স্ট্যাকের উপচে পড়বে না:

var base64 = btoa(
  new Uint8Array(arrayBuffer)
    .reduce((data, byte) => data + String.fromCharCode(byte), '')
);

4
নিশ্চিত যে এটি সত্যই সেক্সি কিনা। সর্বোপরি, আপনি <amount of Bytes in the buffer>নতুন স্ট্রিং তৈরি করছেন ।
নিওনিট

কীভাবে btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))?
রায় টিঙ্কার

35

ব্লব এবং ফাইলরেডার ব্যবহার করার মতো আরও একটি অ্যাসিনক্রোনাস উপায় রয়েছে।

আমি পারফরম্যান্স পরীক্ষা করিনি। তবে এটি ভাবনার আলাদা উপায়।

function arrayBufferToBase64( buffer, callback ) {
    var blob = new Blob([buffer],{type:'application/octet-binary'});
    var reader = new FileReader();
    reader.onload = function(evt){
        var dataurl = evt.target.result;
        callback(dataurl.substr(dataurl.indexOf(',')+1));
    };
    reader.readAsDataURL(blob);
}

//example:
var buf = new Uint8Array([11,22,33]);
arrayBufferToBase64(buf, console.log.bind(console)); //"CxYh"

dataurl.split(',', 2)[1]পরিবর্তে ব্যবহার করুন dataurl.substr(dataurl.indexOf(',')+1)
কার্টার মেডলিন 21

এটি কাজের গ্যারান্টিযুক্ত বলে মনে হয় না। W3c.github.io/FileAPI/#issue-f80bda5b এর মতে readAsDataURLতাত্ত্বিকভাবে একটি শতাংশ এনকোডেড ডেটা ইউআরআই ফেরত দিতে পারে (এবং এটি সম্ভবত জাসডমের ক্ষেত্রেই দেখা যায় )
টিএস

@ কার্টারমেডলিন এর splitচেয়ে ভাল হবে কেন substring?
টিএস

বিভাজন কম হয়। তবে ডেটাআরলে এক বা একাধিক কমা থাকতে পারে (,), বিভাজনটি নিরাপদ নয়।
cuixiping

12

আমি এটি ব্যবহার করেছি এবং আমার জন্য কাজ করে।

function arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}



function base64ToArrayBuffer(base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}

নিরাপদ না. @Chemoish উত্তর দেখুন
কুগেল

11

এর জন্য আমার প্রস্তাবনাটি হ'ল দেশীয় btoaকৌশলগুলি ব্যবহার না করা - কারণ তারা সমস্তগুলি সঠিকভাবে এনকোড করে না ArrayBuffer...

DOMs atob () এবং btoa () পুনরায় লিখুন

যেহেতু ডিওএমএসআরটিংগুলি 16-বিট-এনকোডেড স্ট্রিং রয়েছে তাই বেশিরভাগ ব্রাউজারে উইন্ডো.বিটো কল করে একটি ইউনিকোড স্ট্রিংয়ে একটি অক্ষর 8-বিট ASCII- এনকোডেড অক্ষরের সীমা ছাড়িয়ে গেলে রেঞ্জ ব্যতিক্রমের কারণ হয়ে উঠতে পারে।

যদিও আমি কখনও এই সঠিক ত্রুটির মুখোমুখি হইনি, আমি দেখতে পেয়েছি যে ArrayBufferআমি এনকোড করার চেষ্টা করেছি এমন বেশিরভাগই ভুলভাবে এনকোড করেছে।

আমি হয় MDN সুপারিশ বা সংক্ষেপ ব্যবহার করব would


btoaস্ট্রিংয়ে কাজ করে না, তবে ওপি জিজ্ঞাসা করছে ArrayBuffer
tsh

1
খুব এখানে, এতগুলি স্নিপেটগুলি যা ভুল জিনিসটির প্রস্তাব দেয়! আমি এই ত্রুটিটি একাধিকবার দেখেছি, যেখানে লোকেরা অন্ধভাবে atob এবং btoa ব্যবহার করে।
কুগেল

4
অন্যান্য অ্যারে কৌশলগুলি ব্যবহার করে সমস্ত অ্যারে বাফারগুলি সূক্ষ্মভাবে এনকোড করা উচিত, atob / btoa কেবলমাত্র 0xFF এর চেয়ে বেশি অক্ষর ধারণ করে এমন পাঠ্যের ক্ষেত্রে সমস্যা (যা সংজ্ঞা অনুসারে বাইট অ্যারে দেয় না)। এমডিএন সতর্কতা প্রযোজ্য নয় কারণ অন্যান্য উত্তরে কৌশল ব্যবহার করার সময় আপনার কাছে কেবল স্ট্রিং থাকার গ্যারান্টি রয়েছে যা কেবলমাত্র ইউএসটিআইআরএর কোনও মান 0 এবং 255 এর মধ্যে গ্যারান্টিযুক্ত হিসাবে স্ট্রিং.ফ্রোমচোড়কোড এর গ্যারান্টিযুক্ত হিসাবে কেবল ASCII অক্ষর সমন্বিত থাকে সীমার বাইরে নয় এমন একটি চরিত্র ফিরিয়ে দিতে।
জামেসরনেটর

11
var blob = new Blob([arrayBuffer])

var reader = new FileReader();
reader.onload = function(event){
   var base64 =   event.target.result
};

reader.readAsDataURL(blob);

1
দয়া করে আপনার উত্তরে কিছু ব্যাখ্যা যুক্ত করুন। এই কোড মানে কি?
অস্কার


1
এটি এখন পর্যন্ত দ্রুততম পন্থা - আমার সীমাবদ্ধ পরীক্ষার অন্যান্য দশকের তুলনায় দশগুণ দ্রুত
jitin

আমি আশা করি আমি এই সমাধানটি আবার 8 ঘন্টার মতো খুঁজে পেয়েছি। আমার দিন নষ্ট হত না; (আপনাকে ধন্যবাদ
কায়সার শহীদ

7

Uint8Array কে বেস 64 স্ট্রিংয়ে রূপান্তর করার জন্য নীচে দুটি সাধারণ ফাংশন রয়েছে এবং আবার ফিরে

arrayToBase64String(a) {
    return btoa(String.fromCharCode(...a));
}

base64StringToArray(s) {
    let asciiString = atob(s);
    return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}

1
এটি একটি বিভ্রান্তিকর উত্তর। এটি বৈধ জাভাস্ক্রিপ্টের মতো দেখায় না এবং এটি কোনও Uint8Array একটি অ্যারেবফার?
ব্যবহারকারী 1153660

@ user1153660 functionকীওয়ার্ডটি যুক্ত করুন এবং এটি একটি আধুনিক ব্রাউজারে কাজ করা উচিত।
ইয়েতি

অসাধারণ! btoa (String.fromCharCode (... ক)); ইউিন্ট 8 অ্যারে এনকোড করতে এখন পর্যন্ত আমি সবচেয়ে সংক্ষিপ্ত সংস্করণটি দেখেছি।
নিকোলো

1
এটি দেখতে দুর্দান্ত লাগছে তবে অ্যারেটি যদি খুব বিশাল হয় তবে এটি সর্বোচ্চ কল স্ট্যাকের আকার ত্রুটি ছাড়িয়ে যাবে।
পাউয়েস স্যাজটিć

0

আপনি ArrayBufferব্যবহার করে একটি সাধারণ অ্যারে সংগ্রহ করতে পারেন Array.prototype.sliceArray.prototype.mapবাইটসকে অক্ষরগুলিতে রূপান্তর করতে এবং joinতাদের একসাথে ফর্মার স্ট্রিংয়ে রূপান্তর করতে একটি ফাংশন ব্যবহার করুন ।

function arrayBufferToBase64(ab){

    var dView = new Uint8Array(ab);   //Get a byte view        

    var arr = Array.prototype.slice.call(dView); //Create a normal array        

    var arr1 = arr.map(function(item){        
      return String.fromCharCode(item);    //Convert
    });

    return window.btoa(arr1.join(''));   //Form a string

}

এতে কোনও স্ট্রিং কনটেন্টেশন চলছে না বলে এই পদ্ধতিটি দ্রুত faster


নিরাপদ না. @Chemoish উত্তর দেখুন
কুগেল

0

ওপিতে রানিং এনভায়ারোমেন্ট নির্দিষ্ট করা হয়নি তবে আপনি যদি নোড.জেএস ব্যবহার করেন তবে এ জাতীয় কাজ করার খুব সহজ উপায় আছে।

অফিসিয়াল নোড.জেএস ডক্স https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings এর সাথে অ্যাকর্ডিগ

// This step is only necessary if you don't already have a Buffer Object
const buffer = Buffer.from(yourArrayBuffer);

const base64String = buffer.toString('base64');

এছাড়াও, আপনি উদাহরণস্বরূপ কৌনিক অধীনে চলতে থাকলে, বাফার ক্লাসটি ব্রাউজার পরিবেশেও উপলব্ধ করা হবে।


আপনার উত্তরটি কেবল নোডজেএসে প্রযোজ্য এবং ব্রাউজারে কাজ করবে না।
জাভটিক

1
@ জাভ্যাটিক আমি দেখছি, ওপি স্পষ্টভাবে চলমান পরিবেশকে নির্দিষ্ট করে নি, তাই আমার উত্তরটি ভুল নয়, তিনি কেবল ট্যাগ করেছিলেন Javascript। তাই আমি আমার উত্তরটি আরও সংক্ষিপ্ত করে তুলতে আপডেট করেছি। আমি মনে করি এটি একটি গুরুত্বপূর্ণ উত্তর কারণ আমি কীভাবে এটি করব তা অনুসন্ধান করেছিলাম এবং সমস্যার সর্বোত্তম উত্তর পেতে পারি না।
জোও এডুয়ার্ডো সোয়ারস ই সিলভা

-3

আমার পাশে, ক্রোম নেভিগেটর ব্যবহার করে, একটি অ্যারেবফার পড়তে আমাকে ডেটাভিউ () ব্যবহার করতে হয়েছিল

function _arrayBufferToBase64( tabU8A ) {
var binary = '';
let lecteur_de_donnees = new DataView(tabU8A);
var len = lecteur_de_donnees.byteLength;
var chaine = '';
var pos1;
for (var i = 0; i < len; i++) {
    binary += String.fromCharCode( lecteur_de_donnees.getUint8( i ) );
}
chaine = window.btoa( binary )
return chaine;}

-4
function _arrayBufferToBase64(uarr) {
    var strings = [], chunksize = 0xffff;
    var len = uarr.length;

    for (var i = 0; i * chunksize < len; i++){
        strings.push(String.fromCharCode.apply(null, uarr.subarray(i * chunksize, (i + 1) * chunksize)));
    }

    return strings.join("");
}

এটি স্ট্রিং থেকে সংরক্ষণাগারটি আনপ্যাক করার জন্য জেএসজিপ ব্যবহার করা ভাল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.