자바 스크립트에서 바이트 배열을 문자열로 변환


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

그러나 어떻게 다른 방식으로 작동하는 기능을 얻을 수 있습니까?

감사.

Shao


바이트 배열을 문자열로 변환 하시겠습니까, 아니면 비트 배열을 문자열로 변환 하시겠습니까?
mcandre 2010

또한 utf8 배열에 대한 적절한 솔루션을 참조하십시오 : Uint8Array to string in Javascript
Vadzim

답변:


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메서드가 blob 배열에 비트 문자열이 아닌 10 진수가 포함되어 있다고 예상 하므로 다음과 같이 작성할 수 있습니다.

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 함수를 변경하여 더 많은 Javascript 함수를 사용하여 함수와 하위 함수를 줄일 수 있습니까? .....
user385579 2010-07-07

1
2) 이러한 변환이 필요한 이유는 서명을 캡처하고 데이터베이스의 BLOB 필드를 채우기 위해 변환해야하기 때문입니다. 문제는이 두 기능이 작동하는 동안 다른 문제가 발생한다는 것입니다. 가장 중요한 것은 데이터베이스에서 BLOB를 검색 할 때 바이트 배열 객체로 이동한다는 것입니다. 그러나 원래 함수를 통해 실행 한 후 BLOB를 데이터베이스에 쓸 때 바이트 배열 개체가 아닙니다. 이것이 문제의 원인 일 수 있습니다. 어떤 아이디어?
user385579

dcx.sybase.com/index.html#1101en/ulmbus_en11/… 이것은 데이터를 설정하는 데 사용하는 구문입니다.
user385579

4
String.fromCharCode.apply(String, array)Safari에서 매우 긴 문자열에는 안전하지 않습니다. JavaScriptCore에는 함수가 65536 개 이상의 인수를 사용할 수 없다는 문제가 있습니다. 그렇지 않으면 RangeError가 발생합니다. 또한 그보다 약간 작은 배열에서 브라우저를 잠급니다. 참조 bugs.webkit.org/show_bug.cgi?id=80797
마태 복음

4
다중 바이트 utf-8 문자에 대한 실패 예 : bin2String([0xE2, 0x98, 0xB9])
Brad Kent

49

단순히 apply바이트 배열을String.fromCharCode . 예를 들면

String.fromCharCode.apply(null, [102, 111, 111]) 'foo'와 같습니다.

주의 사항 : 65535보다 짧은 어레이에서 작동합니다. MDN 문서는 여기 .


이것은 이미 6 년 전에 받아 들여진 답변에 의해 입증되었습니다.
발타자르

2
아, 참으로 그 라인을 놓쳤습니다. 기본적으로 나는 짧은 한 줄짜리를 찾고 있었고 길고 편집 된 대답을 무시했습니다 (너무 성급 할 수도 있습니다).
Bogdan D

좋아 오, 메이크업 감각 :
발타자르

11
반복하더라도 그 간결함은 받아 들여지는 대답보다 낫습니다.
Rich Apodaca

23

새로운 Text Encoding 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는 그것을 지원하지 않습니다.
Soul_man

UTF-8 및 IE 지원이 필요한 경우 MDN 웹 사이트 에서 권장 하는 FastestSmallestTextEncoderDecoder 폴리 필 을 사용할 수 있습니다 .
Rosberg Linhares 2019

10

이것은 작동합니다.

String.fromCharCode(...array);

또는

String.fromCodePoint(...array)

짧고 달콤한)
abhisekp

8

string2Bin은 루프없이 훨씬 간결하게 작성 하여 부팅 할 수 있습니다!

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

1
추가 된 함수 호출이이 속도를 늦추는 지 궁금 할 것입니다.
jocull

36
여전히 루프가 있으며 map () 내에 숨겨져 있습니다.
Johannes Lumpe 2013-06-28

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

내가 조금 늦더라도 ES6를 사용하여 한 줄짜리 구현을 공유하는 것이 미래의 사용자에게 흥미로울 것이라고 생각했습니다.

환경 또는 데이터로 무엇을 할 것인지에 따라 내가 중요하다고 생각하는 한 가지는 전체 바이트 값을 유지하는 것입니다. 예를 들어 (5).toString(2)는를 제공 101하지만 완전한 이진 변환은 실제로 이루어집니다 00000101.leftPad 집니다. 따라서 문자열 바이트를 선행 0으로 채우는 구현을 . 그러나 다른 답변과 마찬가지로 전혀 필요하지 않을 수도 있습니다.

아래 코드 조각을 실행하면 첫 번째 출력이 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

node.js 를 사용하는 경우 다음 을 수행 할 수 있습니다.

yourByteArray.toString('base64');

0

UTF-8 문자로 작동하는 솔루션을 찾지 못했습니다. String.fromCharCode2 바이트 문자를 만날 때까지 좋습니다.

예를 들어 Hüser 는 다음과 같이 올 것입니다.[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. Mozilla 개발자 네트워크 웹 사이트 에서 권장 하는 FastestSmallestTextEncoderDecoder 폴리 필을 사용할 수 있습니다. .
  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);


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