जावास्क्रिप्ट में स्ट्रिंग के लिए बाइट सरणी परिवर्तित


81

मैं एक बाइट सरणी को स्ट्रिंग में कैसे बदलूं?

मैंने इन कार्यों को उल्टा पाया है:

function string2Bin(s) {
    var b = new Array();
    var last = s.length;

    for (var i = 0; i < last; i++) {
        var d = s.charCodeAt(i);
        if (d < 128)
            b[i] = dec2Bin(d);
        else {
            var c = s.charAt(i);
            alert(c + ' is NOT an ASCII character');
            b[i] = -1;
        }
    }
    return b;
}

function dec2Bin(d) {
    var b = '';

    for (var i = 0; i < 8; i++) {
        b = (d%2) + b;
        d = Math.floor(d/2);
    }

    return b;
}

लेकिन मैं दूसरे तरीके से काम करने वाले कार्यों को कैसे प्राप्त करूं?

धन्यवाद।

शाओ


क्या आप एक बाइट सरणी को स्ट्रिंग में बदलना चाहते हैं, या बिट्स का एक स्ट्रिंग स्ट्रिंग में?
14

जवाबों:


82

आपको प्रत्येक ओकटेट को वापस संख्या में पार्स करने की आवश्यकता है, और एक चरित्र पाने के लिए उस मूल्य का उपयोग करें, कुछ इस तरह से:

function bin2String(array) {
  var result = "";
  for (var i = 0; i < array.length; i++) {
    result += String.fromCharCode(parseInt(array[i], 2));
  }
  return result;
}

bin2String(["01100110", "01101111", "01101111"]); // "foo"

// Using your string2Bin function to test:
bin2String(string2Bin("hello world")) === "hello world";

संपादित करें: हाँ, आपका करंट string2Binशीघ्र ही और अधिक लिखा जा सकता है:

function string2Bin(str) {
  var result = [];
  for (var i = 0; i < str.length; i++) {
    result.push(str.charCodeAt(i).toString(2));
  }
  return result;
}

लेकिन आपके द्वारा लिंक किए गए दस्तावेज़ को देखकर, मुझे लगता है कि setBytesParameterविधि को उम्मीद है कि बूँद सरणी में दशमलव संख्याएं हैं, थोड़ा स्ट्रिंग नहीं है , इसलिए आप इस तरह से कुछ लिख सकते हैं:

function string2Bin(str) {
  var result = [];
  for (var i = 0; i < str.length; i++) {
    result.push(str.charCodeAt(i));
  }
  return result;
}

function bin2String(array) {
  return String.fromCharCode.apply(String, array);
}

string2Bin('foo'); // [102, 111, 111]
bin2String(string2Bin('foo')) === 'foo'; // true

सुपर स्पीडी प्रतिक्रिया के लिए धन्यवाद। प्रश्नों के युगल ... 1) आपका bin2String फ़ंक्शन प्रभावशाली है - कोड की केवल 5 लाइनें। क्या फ़ंक्शन और उप-फ़ंक्शन को छोटा करने के लिए अधिक जावास्क्रिप्ट कार्यों का उपयोग करने के लिए string2bin फ़ंक्शन को बदला जा सकता है? .....
user385579

1
2) मुझे इन रूपांतरणों की आवश्यकता इसलिए है क्योंकि मैं एक हस्ताक्षर पर कब्जा कर रहा हूं और मुझे डेटाबेस में एक BLOB क्षेत्र को आबाद करने के लिए इसे बदलना होगा। समस्या यह है कि इन 2 कार्यों के कार्य के दौरान, कुछ और गलत हो रहा है। मुख्य बात यह है कि जब मैं डेटाबेस से एक BLOB प्राप्त करता हूं तो यह बाइट्स सरणी ऑब्जेक्ट में जाता है। हालाँकि, जब मैं मूल फ़ंक्शन के माध्यम से इसे चलाने के बाद डेटाबेस को BLOB लिख रहा हूं तो यह बाइट्स ऐरे ऑब्जेक्ट नहीं है। यह समस्या का कारण हो सकता है। कोई विचार?
user385579

dcx.sybase.com/index.html#1101en/ulmbus_en11/… यह डेटा सेट करने के लिए उपयोग किए जाने वाले वाक्यविन्यास है।
user385579

4
String.fromCharCode.apply(String, array)सफारी में बहुत लंबे तार के लिए असुरक्षित है। JavaScriptCore में एक समस्या है जिसका अर्थ है कि फ़ंक्शन 65536 से अधिक तर्क नहीं ले सकते हैं, या एक रेंजऑयर को फेंक दिया जाएगा। यह ब्राउज़र को इससे छोटे से छोटे एरेज़ पर भी लॉक कर देता है। Bugs.webkit.org/show_bug.cgi?id=80797
मैथ्यू

4
मल्टी-बाइट utf-8 वर्णों के लिए विफल रहता है: bin2String([0xE2, 0x98, 0xB9])
ब्रैड केंट

49

बस applyअपने बाइट सरणी करने के लिए String.fromCharCode। उदाहरण के लिए

String.fromCharCode.apply(null, [102, 111, 111]) 'फू' के बराबर है।

कैविएट: 65535 से कम सरणियों के लिए काम करता है। एमडीएन डॉक्स यहां


यह पहले से ही 6 साल पहले स्वीकृत उत्तर द्वारा प्रदर्शित किया गया है।
Balthazar

2
आह, वास्तव में, मैं उस लाइन को याद किया। मूल रूप से मैं एक लघु-लाइनर की तलाश में था और मैंने उस लंबे और संपादित उत्तर (शायद बहुत जल्दबाजी में) को खारिज कर दिया।
बोगडान डी

ओह ठीक है जो समझ में आता है :)
बाल्त्झार

11
एक पुनरावृति होने पर भी, इसकी संक्षिप्तता इसे स्वीकृत उत्तर से बेहतर बनाती है।
अमीर अपोडका

23

नया पाठ एन्कोडिंग API आज़माएँ:

// create an array view of some valid bytes
let bytesView = new Uint8Array([104, 101, 108, 108, 111]);

console.log(bytesView);

// convert bytes to string
// encoding can be specfied, defaults to utf-8 which is ascii.
let str = new TextDecoder().decode(bytesView); 

console.log(str);

// convert string to bytes
// encoding can be specfied, defaults to utf-8 which is ascii.
let bytes2 = new TextEncoder().encode(str);

// look, they're the same!
console.log(bytes2);
console.log(bytesView);


1
दुर्भाग्य से IE इसका समर्थन नहीं करता है।
सोल_मन

यदि आपको UTF-8 और IE समर्थन की आवश्यकता है, तो आप MDN वेबसाइट द्वारा सुझाए गए FastestSmallestTextEncoderDecoder polyfill का उपयोग कर सकते हैं ।
रोसबर्ग लीन्हारेस


8

उस string2Bin को और भी सलीके से लिखा जा सकता है , और बिना किसी लूप के, बूट करने के लिए!

function string2Bin ( str ) {
    return str.split("").map( function( val ) { 
        return val.charCodeAt( 0 ); 
    } );
}

1
यह देखने के लिए उत्सुक होंगे कि क्या जोड़ा गया फ़ंक्शन कॉल इसे धीमा करता है।
jocull

36
इसमें अभी भी एक लूप है, यह सिर्फ नक्शे () के भीतर छिपा है।
जोहान्स लुम्पे

4

मुझे लगता है कि यह अधिक कुशल होगा:

function toBinString (arr) {
    var uarr = new Uint8Array(arr.map(function(x){return parseInt(x,2)}));
    var strings = [], chunksize = 0xffff;
    // There is a maximum stack size. We cannot call String.fromCharCode with as many arguments as we want
    for (var i=0; i*chunksize < uarr.length; i++){
        strings.push(String.fromCharCode.apply(null, uarr.subarray(i*chunksize, (i+1)*chunksize)));
    }
    return strings.join('');
}

4

यहां तक ​​कि अगर मुझे थोड़ा देर हो गई है, तो मैंने सोचा कि भविष्य के उपयोगकर्ताओं के लिए कुछ एकल-लाइनर कार्यान्वयन को साझा करना दिलचस्प होगा जो मैंने ईएस 6 का उपयोग करके किया था।

एक बात जो मैं आपके पर्यावरण या / और आप डेटा के साथ क्या करूंगा, इस पर निर्भर करता है कि आप पूर्ण बाइट मान का संरक्षण करें। उदाहरण के लिए, (5).toString(2)आपको दे देंगे 101, लेकिन पूर्ण द्विआधारी रूपांतरण वास्तविकता में है 00000101, और इसीलिए आपको leftPadअग्रणी शून्य के साथ स्ट्रिंग बाइट को भरने के लिए एक कार्यान्वयन बनाने की आवश्यकता हो सकती है । लेकिन आपको इसकी आवश्यकता बिल्कुल नहीं होगी, जैसे कि अन्य उत्तर प्रदर्शित किए गए हैं।

यदि आप नीचे दिए गए कोड स्निपेट को चलाते हैं, तो आप पहले आउटपुट को abcस्ट्रिंग के रूपांतरण को बाइट सरणी में देखते हैं और उसके ठीक बाद उसी सरणी को फिर से स्ट्रिंग के लिए कहा गया।

// For each byte in our array, retrieve the char code value of the binary value
const binArrayToString = array => array.map(byte => String.fromCharCode(parseInt(byte, 2))).join('')

// Basic left pad implementation to ensure string is on 8 bits
const leftPad = str => str.length < 8 ? (Array(8).join('0') + str).slice(-8) : str

// For each char of the string, get the int code and convert it to binary. Ensure 8 bits.
const stringToBinArray = str => str.split('').map(c => leftPad(c.charCodeAt().toString(2)))

const array = stringToBinArray('abc')

console.log(array)
console.log(binArrayToString(array))


3

स्ट्रिंग बाइट सरणी: "FooBar".split('').map(c => c.charCodeAt(0));

बाइट सरणी से स्ट्रिंग: [102, 111, 111, 98, 97, 114].map(c => String.fromCharCode(c)).join('');


सावधान रहें, यह IE द्वारा समर्थित नहीं है!
tedebus

1

उत्तर देने में बहुत देर हो गई लेकिन यदि आपका इनपुट ASCII बाइट्स के रूप में है, तो आप इस समाधान की कोशिश कर सकते हैं:

function convertArrToString(rArr){
 //Step 1: Convert each element to character
 let tmpArr = new Array();
 rArr.forEach(function(element,index){
    tmpArr.push(String.fromCharCode(element));
});
//Step 2: Return the string by joining the elements
return(tmpArr.join(""));
}

function convertArrToHexNumber(rArr){
  return(parseInt(convertArrToString(rArr),16));
}

1

यदि आप नोड का उपयोग कर रहे हैं। तो क्या आप ऐसा कर सकते हैं:

yourByteArray.toString('base64');

0

यूटीएफ -8 वर्णों के साथ काम करने वाला कोई भी समाधान नहीं मिला। String.fromCharCodeअच्छा है जब तक आप 2 बाइट चरित्र से मिलते हैं।

उदाहरण के लिए हुसेर आएगा[0x44,0x61,0x6e,0x69,0x65,0x6c,0x61,0x20,0x48,0xc3,0xbc,0x73,0x65,0x72]

लेकिन अगर आप यह माध्यम से जाने के साथ String.fromCharCodeआप होगा Hüser के रूप में प्रत्येक बाइट एक चार के लिए अलग से परिवर्तित किया जाएगा।

उपाय

वर्तमान में मैं निम्नलिखित समाधान का उपयोग कर रहा हूं:

function pad(n) { return (n.length < 2 ? '0' + n : n); }
function decodeUtf8(data) {
  return decodeURIComponent(
    data.map(byte => ('%' + pad(byte.toString(16)))).join('')
  );
}

0

मेरे पास कुछ डिक्रिप्टेड बाइट ऐरे हैं जिनमें पैडिंग कैरेक्टर और अन्य सामान जिनकी मुझे जरूरत नहीं थी, इसलिए मैंने ऐसा किया (शायद यह सही नहीं है, लेकिन यह मेरे सीमित उपयोग के लिए काम करता है)

var junk = String.fromCharCode.apply(null, res).split('').map(char => char.charCodeAt(0) <= 127 && char.charCodeAt(0) >= 32 ? char : '').join('');

0

यदि आपकी सरणी UTF-8 में एन्कोडेड है और आप IE पर समर्थित नहीं है, क्योंकि आप TextDecoder API का उपयोग नहीं कर सकते हैं :

  1. आप मोज़िला डेवलपर नेटवर्क वेबसाइट द्वारा अनुशंसित FastestSmallestTextEncoderDecoder polyfill का उपयोग कर सकते हैं ;
  2. आप MDN वेबसाइट पर दिए गए इस फ़ंक्शन का उपयोग कर सकते हैं :

function utf8ArrayToString(aBytes) {
    var sView = "";
    
    for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {
        nPart = aBytes[nIdx];
        
        sView += String.fromCharCode(
            nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */
                /* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */
                (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
            : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */
                (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
            : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */
                (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
            : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */
                (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
            : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */
                (nPart - 192 << 6) + aBytes[++nIdx] - 128
            : /* nPart < 127 ? */ /* one byte */
                nPart
        );
    }
    
    return sView;
}

let str = utf8ArrayToString([50,72,226,130,130,32,43,32,79,226,130,130,32,226,135,140,32,50,72,226,130,130,79]);

// Must show 2H₂ + O₂ ⇌ 2H₂O
console.log(str);


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.