2016-09-10 5 views
2

필자는 UTF-32 (그러나 더 높은 16 비트는 항상 0) 코드 포인트를 보유하는 문자열을 가지고 있습니다. 각 토큰은 긴. 자 열의 각. 자 코드 포인트 4 바이트 중 1입니다. 바이트가 문자열로 바뀌기 전에 부호있는 int로 해석된다는 점에 유의하십시오.JavaScript : 멀티 바이트 문자열 배열을 32 비트 int 배열로 변환하는 방법?

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

이 일을 더 나은, 간단한 및/또는보다 효율적인 방법이 있나요?

내가 답변 코드 snipets 수십 내 입력 바이트 서명하는 int 문자열에있는 문제를 해결 비슷한 일하지만 아무것도 거래를 보았다 : S

편집 :이 코드는 늘 가장 높은 작업 1 < < 32 이후의 코드 포인트는 2^32가 아니라 1입니다.

+0

사실 T.J.Crowder @, UTF-32. 추가하려면 편집하십시오. – TigerShark

답변

1

멋진 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)"); 
 
}