2016-09-10 3 views
2

私はUTF-32を保持する文字列を持っていますが(おそらく上位16ビットは常に0になります)、コードポイントです。各トークンは、長い文字列の各文字のコードポイントの4バイトのうちの1つです。 文字列に変換する前に、バイトが符号付き整数として解釈されることに注意してください。JavaScript:マルチバイト文字列配列を32ビット整数配列に変換するにはどうすればよいですか?

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

これを行うには、より良い、より単純なおよび/またはより効率的な方法はありますか?

私は私の入力バイトが署名したint型の列にある問題に対処する同様のことが、何に対処するための答えとコードsnipetsの数十を見てきました:S

編集:このコードは文句を言わない最高と連携1 < < 32は1であり2^32ではないので、コードポイント

+0

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

コメントで詳細な説明と例:確かにT.J.Crowder @

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

関連する問題