JavaScript : 멀티 바이트 문자열 배열을 32 비트 정수 배열로 변환하는 방법은 무엇입니까?

범 상어

UTF-32 (하지만 더 높은 16 비트는 항상 0) 코드 포인트를 보유하는 문자열이 있습니다. 각 토큰은 긴 문자열에있는 각 문자의 코드 포인트 4 바이트 중 하나입니다. 바이트는 문자열로 변환되기 전에 부호있는 정수로 해석되므로 이에 대해 제어 할 수 없습니다.

    // Provided: 
    intEncodedBytesString= "0,0,0,-31,0,0,0,-15,0,0,0,-31"; //3 chars: áñá

    // Wanted
    actualCodePoints = [225,241,225];

intEncodedBytesString을 actualCodePoints 배열로 바꿔야합니다. 지금까지 나는 이것을 생각해 냈습니다.

var intEncodedBytesStringArray = intEncodedBytesString.toString().split(',');
var i, str = '';
var charAmount = intEncodedBytesStringArray.length / 4;

for (i = 0; i < charAmount; i++) {
  var codePoint = 0;

  for (var j = 0; j < 4; j++) {
    var num = parseInt(intEncodedBytesStringArray[i * 4 + j], 10);
    if (num != 0) {
      if (num < 0) {
        num = (1 << (8 * (4 - j))) + num;
      }

      codePoint += (num << (8 * (3 - j)));
    }
  }

  str += String.fromCodePoint(codePoint);
}

이 작업을 수행하는 더 좋고 간단하며 효율적인 방법이 있습니까?

비슷한 일을 처리하기 위해 수십 개의 답변과 코드 조각을 보았지만 입력 바이트가 서명 된 정수 문자열에 있다는 문제는 해결하지 못했습니다.

편집 :이 코드는 1 << 32가 2 ^ 32가 아니라 1이기 때문에 가장 높은 코드 포인트에서는 작동하지 않습니다.

TJ 크라우 더

멋지고 단순한 UTF-32이기 때문에 더 간단한 방법이 있습니다. 4 바이트 블록으로 작업하면됩니다. 또한 가능한 부정성을 처리하는 간단한 방법은 (value + 256) % 256.

그래서:

var intEncodedBytesString = "0,0,0,-31,0,0,0,-15,0,0,0,-31"; //3 char
var actualCodePoints = [];
var bytes = intEncodedBytesString.split(",").map(Number);
for (var i = 0; i < bytes.length; i += 4) {
  actualCodePoints.push(
       (((bytes[i]     + 256) % 256) << 24) +
       (((bytes[i + 1] + 256) % 256) << 16) +
       (((bytes[i + 2] + 256) % 256) << 8) +
       (bytes[i + 3]   + 256) % 256
  );
}

주석에 자세한 설명이있는 예 :

// Starting point
var intEncodedBytesString = "0,0,0,-31,0,0,0,-15,0,0,0,-31"; //3 char
// Target array
var actualCodePoints = [];
// Get the bytes as numbers by splitting on comman running the array
// through Number to convert to number.
var bytes = intEncodedBytesString.split(",").map(Number);

// Loop through the bytes building code points
var i, cp;
for (i = 0; i < bytes.length; i += 4) {
  // (x + 256) % 256 will handle turning (for instance) -31 into 224
  // We shift the value for the first byte left 24 bits, the next byte 16 bits,
  // the next 8 bits, and don't shift the last one at all. Adding them all
  // together gives us the code point, which we push into the array.
  cp = (((bytes[i]     + 256) % 256) << 24) +
       (((bytes[i + 1] + 256) % 256) << 16) +
       (((bytes[i + 2] + 256) % 256) << 8) +
       (bytes[i + 3]   + 256) % 256;
  actualCodePoints.push(cp);
}

// Show the result
console.log(actualCodePoints);

// If the JavaScript engine supports it, show the string
if (String.fromCodePoint) { // ES2015+
  var str = String.fromCodePoint.apply(String, actualCodePoints);
  // The above could be
  // `let str = String.fromCodePoint(...actualCodePoints);`
  // on an ES2015+ engine
  console.log(str);
} else {
  console.log("(Your browser doesn't support String.fromCodePoint)");
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관