【问题标题】:Convert a 32bit integer into 4 bytes of data in javascript在javascript中将32位整数转换为4字节数据
【发布时间】:2013-04-02 10:28:23
【问题描述】:

我被要求将整数转换为 32 位二进制数。 因此使用integer.toString(2) 并以0 和1 的32 位二进制格式获得所需的值。但实际上我被要求做的是将整数转换为 4 个字节的数据。 我无法按照建议获得输出。我用过integer.toString(8)integer.toString(16)。但没用。

例子:

 num=1065489844 
 num.toString(2) //Output: 111111100000100001010110110100
 num.toString(8) //Output: 7740412664

请告诉我,我的不足之处。

【问题讨论】:

  • 字符串通常与二进制数据不同。如果您可以使用 256 的基数,它们将是相同的,但 toString() 仅支持最多 36 的基数。
  • 您希望输出是什么?不清楚预期的 4 字节输出应该是什么样子?
  • 假设您的整数存储在变量x 中。然后使用x | 0 将确保它是一个 32 位整数。我不知道您所说的“二进制数”是什么意思。每种编程语言中的每个整数都存储为位。
  • 32 位是 4 个字节。你已经完成了。

标签: javascript


【解决方案1】:

现在您可以使用ArrayBufferDataView。它们是原生的,因此如果您需要经常使用它,性能会更好。

function toBytesInt32 (num) {
    arr = new ArrayBuffer(4); // an Int32 takes 4 bytes
    view = new DataView(arr);
    view.setUint32(0, num, false); // byteOffset = 0; litteEndian = false
    return arr;
}

等于

function toBytesInt32 (num) {
    arr = new Uint8Array([
         (num & 0xff000000) >> 24,
         (num & 0x00ff0000) >> 16,
         (num & 0x0000ff00) >> 8,
         (num & 0x000000ff)
    ]);
    return arr.buffer;
}

它使用 javascript 位运算符来实现。

【讨论】:

  • 看看为什么(uint8) (num & 0xFF000000) >> 24 适用于例如num = 0xF0000000:>> 运算符将其操作数转换为 32 位二补码,因此 0xF0000000 溢出到 -0x0FFFFFFF,然后转移到 -0x0F。然后 Uint8Array 通过取 -0x0F0xFF 将其值转换为无符号 8 位整数(这里的模不是 % 运算符,但根据 JS 规范总是返回正结果)。正如预期的那样,结果最终是0xF0。会是一个很好的面试问题;)
【解决方案2】:

SEIAROTg 的回答没有输出字符串。我已经对正数和负数进行了全面测试,这段代码会给你一个 4 字节的字符串输出,代表大端格式的数字(2 的补码 0xFFFFFFFF = -1)。

var toBytesInt32=function(num) {
    var ascii='';
    for (let i=3;i>=0;i--) {
        ascii+=String.fromCharCode((num>>(8*i))&255);
    }
    return ascii;
};

顺便说一句,如果你想反其道而行之,你可以使用

var fromBytesInt32=function(numString) {
    var result=0;
    for (let i=3;i>=0;i--) {
        result+=numString.charCodeAt(3-i)<<(8*i);
    }
    return result;
};

将 4 字节字符串转换为整数

【讨论】:

  • 这是一个 javascript 限制。 Javascript 将任何第一个数字为 1 的 32 位数字视为负数。
  • 我对您的代码做出了错误的假设。您的答案适用于 negative 和 positive 参数,只要它们在 (signed) 32 位整数的范围内。我将删除我的 cmets,很抱歉造成混乱
  • +1,如果空间效率至关重要,则非常适合存储带符号的 32 位 int。我在 Google Apps 脚本中使用它来保存大量具有有限存储空间的 CRC-32 校验和(每个用户存储空间 500 kB,键和值必须是字符串)。顺便说一句:我刚刚测试了整个 int32 范围(从 -2^312^31 - 1)的两个函数,效果很好。
【解决方案3】:

如果你需要一个十六进制格式的输出,这里是代码。

/* Convert value as 8-bit unsigned integer to 2 digit hexadecimal number. */

function hex8(val) {
    val &= 0xFF;
    var hex = val.toString(16).toUpperCase();
    return ("00" + hex).slice(-2);
}

/* Convert value as 16-bit unsigned integer to 4 digit hexadecimal number. */

function hex16(val) {
    val &= 0xFFFF;
    var hex = val.toString(16).toUpperCase();
    return ("0000" + hex).slice(-4);
}

/* Convert value as 32-bit unsigned integer to 8 digit hexadecimal number. */

function hex32(val) {
    val &= 0xFFFFFFFF;
    var hex = val.toString(16).toUpperCase();
    return ("00000000" + hex).slice(-8);
}


var num = 1065489844;
console.log("0x" + hex32(num)); // will output 0x3F8215B4 

【讨论】:

  • 我做的是,我使用num.tostring(2)并将值发送到一个文本文件,经过观察,我发现文本文件的大小是32字节,而不是4字节。所以正如@unwind 提到的,我需要使用 256 的基数。请谁能告诉我,如何使用 256 的基数来获取实际的二进制数。
  • 您需要将数据保存为二进制(而不是 ASCII),因此文件大小为 4 字节。
  • 以下代码允许您下载一个包含二进制格式的 num 的文件。文件大小为 4 字节。 ` 函数 generateData(num) { var data = new Uint8Array(4); for (var i = 0; i > (i * 8)) & 0xff; } var blob = new Blob([data], { type : 'Application/octet-stream' });返回 window.URL.createObjectURL(blob); } 变量数 = 1065489844; document.write('下载');`
  • 该文件应包含二进制数,该文件的大小应为 4 个字节。文件大小设置为 4 字节,但我看不到其中的值。
  • 您可以使用 hexedit 以二进制模式查看文件的内容。在 javascript 中,使用 fileReader API,您可以将文件作为二进制内容打开,然后您可以处理其内容。有关 fileReader API 的更多信息,请参阅教程 (html5rocks.com/en/tutorials/file/dndfiles/#toc-reading-files)
猜你喜欢
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2015-03-21
  • 1970-01-01
  • 2015-09-30
  • 2016-11-30
相关资源
最近更新 更多