簡體   English   中英

在JavaScript中將字節數組轉換為數字

[英]Convert byte array to numbers in JavaScript

我有JavaScript代碼,可從Web服務檢索數值向量。 原始數據是一個雙精度數組,轉換為字節數組然后進行base64編碼。 我在JavaScript中從base64解碼,但后來我不知道如何將結果字節轉換為數字數組。

這是我能想到的唯一方法。

function bytesToDouble(str,start) {
    start *= 8;
    var data = [str.charCodeAt(start+7),
                str.charCodeAt(start+6),
                str.charCodeAt(start+5),
                str.charCodeAt(start+4),
                str.charCodeAt(start+3),
                str.charCodeAt(start+2),
                str.charCodeAt(start+1),
                str.charCodeAt(start+0)];

    var sign = (data[0] & 1<<7)>>7;

    var exponent = (((data[0] & 127) << 4) | (data[1]&(15<<4))>>4);

    if(exponent == 0) return 0;
    if(exponent == 0x7ff) return (sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;

    var mul = Math.pow(2,exponent - 1023 - 52);
    var mantissa = data[7]+
        data[6]*Math.pow(2,8*1)+
        data[5]*Math.pow(2,8*2)+
        data[4]*Math.pow(2,8*3)+
        data[3]*Math.pow(2,8*4)+
        data[2]*Math.pow(2,8*5)+
        (data[1]&15)*Math.pow(2,8*6)+
        Math.pow(2,52);

    return Math.pow(-1,sign)*mantissa*mul;
}

var data = atob("AAAAAABsskAAAAAAAPmxQAAAAAAAKrF");

alert(bytesToDouble(data,0)); // 4716.0
alert(bytesToDouble(data,1)); // 4601.0

這應該會給你一個正確的方向,雖然我花了一段時間來記住如何處理雙打

但需要注意的一個重要注意事項:

這依賴於atob來進行base64解碼,但並非所有地方都支持該解碼,無論如何這都不是一個好主意。 您真正想要做的是將base64編碼的字符串展開為一個數字數組(雖然不是地球上最高效的字節,但使用字節最容易)。 原因是當atob其魔力時,它返回一個字符串,這遠非理想。 根據其映射到的代碼點的編碼(特別是對於128到255之間的代碼點),生成的.charCodeAt()可能不會返回您期望的結果。

並且可能存在一些准確性問題,因為畢竟我使用雙倍來計算雙倍,但我認為它可能沒問題。

使用Base64非常簡單,因此您應該能夠找出該部分。

如果確實切換到數組(而不是現在的str字符串),那么顯然您將刪除.charCodeAt()引用,而直接獲取所需的索引。

這里有一個運轉中的小提琴

我假設我們已經在Web服務(c#)中使用此函數將雙數組數據編碼為字符串:

//Input: [552.4, 539.8]
//Output: IOz0gCAsscA=

private string ConvertToSerializableString(double[] input)
{
  byte[] data = new byte[input.Length * 4];
  for (int i = 0; i < input.Length; i++)
  {
    int source = (int)(input[i] * 1E6);    
    int dataIndex = i * 4;
    data[dataIndex] = (byte)((source >> 24) & 0xFF);
    data[dataIndex + 1] = (byte)((source >> 16) & 0xFF);
    data[dataIndex + 2] = (byte)((source >> 8) & 0xFF);
    data[dataIndex + 3] = (byte)(source & 0xFF);
  }

  return Convert.ToBase64String(data);          
}

然后我們可以使用以下客戶端腳本(javascript)對其進行解碼:

var base64EncodedDoubleArrayData = "IOz0gCAsscA=";
var byteData = window.atob(base64EncodedDoubleArrayData);                

var doubleArray = [];
for (var iColumn = 0; iColumn < byteData.length; iColumn = iColumn + 4) 
{
   var item = (byteData.charCodeAt(iColumn) << 24) + (byteData.charCodeAt(iColumn + 1) << 16) + (byteData.charCodeAt(iColumn + 2) << 8) + byteData.charCodeAt(iColumn + 3);   
   var doubleResult = parseFloat(item/1e6);
   doubleArray.push(doubleResult);
}  

//it should return something like doubleArray = [552.4, 539.8]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM