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

Renato Mangini

ArrayBuffer는 원시 데이터를 전송하는 데 사용되며, WebSockets, Web Intents 2](https://www.html5rocks.com/en/tutorials/file/xhr2/) 및 WebWorkers 등 여러 새로운 API에서 원시 데이터를 사용합니다. 그러나 최근에 JavaScript에 들어왔기 때문에 잘못 해석되거나 오용되는 경우가 있습니다.

의미론적으로 ArrayBuffer는 특정 마스크를 통해 조회된 바이트의 배열입니다. 이 마스크(ArrayBufferView 인스턴스)는 콘텐츠의 예상 구조와 일치하도록 바이트가 정렬되는 방식을 정의합니다. 예를 들어 ArrayBuffer의 바이트가 16비트의 부호 없는 정수 배열을 나타낸다는 사실을 알고 있다면 Uint16Array 뷰에 ArrayBuffer를 래핑하고 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는 실제로 바이트 배열이므로 이 변환 시 양측에서 String의 문자를 바이트로 표현하는 방법에 동의해야 합니다. 이 '계약'을 이전에 본 적이 있을 것입니다. 이는 문자열의 문자 인코딩이며 일반적인 '계약 용어'는 유니코드 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에서는 FileReader/Blob 메서드를 사용하는 것보다 이 도움말의 직접적인 ArrayBuffer 조작 코드를 사용하는 것이 약 27배 더 빠릅니다.