[javascript] JavaScript의 문자열 길이 (바이트)

내 JavaScript 코드에서 다음 형식으로 서버에 메시지를 작성해야합니다.

<size in bytes>CRLF
<data>CRLF

예:

3
foo

데이터에는 유니 코드 문자가 포함될 수 있습니다. UTF-8로 보내야합니다.

JavaScript에서 문자열 길이를 바이트 단위로 계산하는 가장 크로스 브라우저 방법을 찾고 있습니다.

내 페이로드를 구성하기 위해 이것을 시도했습니다.

return unescape(encodeURIComponent(str)).length + "\n" + str + "\n"

그러나 이전 브라우저 (또는 UTF-16 브라우저의 문자열)에 대한 정확한 결과를 제공하지 않습니다.

단서가 있습니까?

최신 정보:

예 : ЭЭХ! Naïve?UTF-8 의 문자열 길이 (바이트) 는 15 바이트이지만 일부 브라우저에서는 대신 23 바이트를보고합니다.



답변

기본적으로 JavaScript에서 수행 할 수있는 방법은 없습니다. ( 현대적인 접근 방식에 대해서는 Riccardo Galli의 답변 을 참조하십시오 .)


기록 참조 또는 TextEncoder API를 여전히 사용할 수없는 경우 .

문자 인코딩을 알고 있다면 직접 계산할 수 있습니다.

encodeURIComponent UTF-8을 문자 인코딩으로 가정하므로 인코딩이 필요하면 할 수 있습니다.

function lengthInUtf8Bytes(str) {
  // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
  var m = encodeURIComponent(str).match(/%[89ABab]/g);
  return str.length + (m ? m.length : 0);
}

이는 UTF-8이 멀티 바이트 시퀀스를 인코딩하는 방식 때문에 작동합니다. 첫 번째 인코딩 된 바이트는 항상 단일 바이트 시퀀스의 경우 0의 상위 비트 또는 첫 번째 16 진수 숫자가 C, D, E 또는 F 인 바이트로 시작합니다. 두 번째 및 후속 바이트는 처음 두 비트가 10 인 바이트입니다. . UTF-8로 계산하려는 추가 바이트입니다.

위키 백과 의 표를 통해 더 명확하게

Bits        Last code point Byte 1          Byte 2          Byte 3
  7         U+007F          0xxxxxxx
 11         U+07FF          110xxxxx        10xxxxxx
 16         U+FFFF          1110xxxx        10xxxxxx        10xxxxxx
...

대신 페이지 인코딩을 이해해야하는 경우 다음 트릭을 사용할 수 있습니다.

function lengthInPageEncoding(s) {
  var a = document.createElement('A');
  a.href = '#' + s;
  var sEncoded = a.href;
  sEncoded = sEncoded.substring(sEncoded.indexOf('#') + 1);
  var m = sEncoded.match(/%[0-9a-f]{2}/g);
  return sEncoded.length - (m ? m.length * 2 : 0);
}


답변

몇 년이 지났고 요즘에는 기본적으로 할 수 있습니다.

(new TextEncoder().encode('foo')).length

IE (또는 Edge)에서는 아직 지원되지 않습니다 ( 폴리 필사용할있습니다 ).

MDN 문서

표준 사양


답변

다음은 정규 표현식을 사용하지 않고 encodeURIComponent ()를 사용하지 않는 훨씬 빠른 버전입니다 .

function byteLength(str) {
  // returns the byte length of an utf8 string
  var s = str.length;
  for (var i=str.length-1; i>=0; i--) {
    var code = str.charCodeAt(i);
    if (code > 0x7f && code <= 0x7ff) s++;
    else if (code > 0x7ff && code <= 0xffff) s+=2;
    if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
  }
  return s;
}

다음은 성능 비교 입니다.

charCodeAt ()에 의해 반환 된 각 유니 코드 코드 포인트의 길이를 UTF8로 계산합니다 (위키 백과의 UTF8 설명 및 UTF16 대리 문자에 따라).

RFC3629 (UTF-8 문자의 길이는 최대 4 바이트)를 따릅니다 .


답변

간단한 UTF-8 인코딩의 경우.보다 약간 더 호환성이 좋은 TextEncoderBlob이 트릭을 수행합니다. 하지만 아주 오래된 브라우저에서는 작동하지 않습니다.

new Blob(["?"]).size; // -> 4  


답변

이 함수는 전달한 UTF-8 문자열의 바이트 크기를 반환합니다.

function byteCount(s) {
    return encodeURI(s).split(/%..|./).length - 1;
}

출처


답변

Buffer(NodeJS 전용)을 사용하는 또 다른 매우 간단한 접근 방식 :

Buffer.byteLength(string, 'utf8')

Buffer.from(string).length


답변

React Native에 대한 솔루션을 찾는 데 시간이 걸리므로 여기에 넣겠습니다.

먼저 buffer패키지를 설치하십시오 .

npm install --save buffer

그런 다음 노드 메소드를 사용하십시오.

const { Buffer } = require('buffer');
const length = Buffer.byteLength(string, 'utf-8');