ArrayBuffer를 문자열로 변환하거나 문자열로 변환하는 방법

Renato Mangini

ArrayBuffer는 원시 데이터를 전송하는 데 사용되며 WebSockets, Web Intents 2](https://www.html5rocks.com/ko/tutorials/file/xhr2/) 및 WebWorkers를 비롯한 여러 새로운 API가 이를 사용합니다. 하지만 최근에 JavaScript 세계에 도입되었기 때문에 오해되거나 오용되는 경우가 있습니다.

의미론적으로 ArrayBuffer는 특정 마스크를 통해 표시되는 바이트 배열일 뿐입니다. 이 마스크(ArrayBufferView의 인스턴스)는 콘텐츠의 예상 구조와 일치하도록 바이트가 정렬되는 방식을 정의합니다. 예를 들어 ArrayBuffer의 바이트가 16비트 부호 없는 정수 배열을 나타낸다는 것을 알고 있다면 ArrayBuffer를 Uint16Array 뷰로 래핑하기만 하면 됩니다. 그러면 Uint16Array가 정수 배열인 것처럼 대괄호 문법을 사용하여 요소를 조작할 수 있습니다.

// suppose buf contains the bytes [0x02, 0x01, 0x03, 0x07]
// notice the multibyte values respect the hardware endianess, which is little-endian in x86
var bufView = new Uint16Array(buf);
if (bufView[0]===258) {   // 258 === 0x0102
    console.log("ok");
}
bufView[0] = 255;    // buf now contains the bytes [0xFF, 0x00, 0x03, 0x07]
bufView[0] = 0xff05; // buf now contains the bytes [0x05, 0xFF, 0x03, 0x07]
bufView[1] = 0x0210; // buf now contains the bytes [0x05, 0xFF, 0x10, 0x02]

ArrayBuffer에 관한 일반적인 실용적인 질문 중 하나는 StringArrayBuffer로 변환하는 방법과 그 반대의 경우를 알아내는 것입니다. ArrayBuffer는 실제로 바이트 배열이므로 이 변환을 위해서는 양쪽 모두 문자열의 문자를 바이트로 표현하는 방법에 동의해야 합니다. 이 '계약'은 이전에 본 적이 있을 것입니다. 문자열의 문자 인코딩입니다. 일반적인 '계약 약관'은 예를 들어 유니코드 UTF-16 및 iso8859-1입니다. 따라서 나와 상대방이 UTF-16 인코딩에 동의했다고 가정하면 변환 코드는 다음과 같을 수 있습니다.

function ab2str(buf) {
    return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function str2ab(str) {
    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
    var bufView = new Uint16Array(buf);
    for (var i=0, strLen=str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

Uint16Array의 사용의 유의 사항. ArrayBuffer의 바이트를 16비트 요소로 정렬하는 ArrayBuffer 뷰입니다. 문자 인코딩 자체는 처리하지 않으며, 이는 String.fromCharCodestr.charCodeAt에서 유니코드로 처리됩니다.

이와 관련된 인기 StackOverflow 질문에는 변환에 관한 다소 복잡한 솔루션이 포함된 인기 답변이 있습니다. 변환 도구 역할을 하는 FileReader를 만들고 문자열이 포함된 Blob를 여기에 제공합니다. 이 방법은 작동하지만 가독성이 좋지 않고 속도가 느린 것 같습니다. 근거 없는 의심이 인류 역사에서 많은 실수를 야기했으므로 여기서는 더 과학적인 접근 방식을 취하겠습니다. 두 메서드를 jsperf로 실행한 결과 의심을 확인할 수 있었습니다. 여기에서 데모를 확인해 보세요.

Chrome 20에서는 이 도움말의 직접 ArrayBuffer 조작 코드를 사용하는 것이 FileReader/Blob 메서드를 사용하는 것보다 거의 27배 빠릅니다.