【问题标题】:javascript: convert binary string to UInt32 big-endian without use of bitwise operationsjavascript:将二进制字符串转换为 UInt32 big-endian 而不使用按位运算
【发布时间】:2016-06-08 10:48:15
【问题描述】:

我正在编写一个共享代码库,我们有一个“禁止按位运算”的 linting 规则。但是,我正在使用一个简短的实用程序函数将二进制字符串转换为无符号 int 32,big-endian。效果很好:

// converts a four-character string into a big endian 32-bit unsigned integer
stringAsUInt32BE(binString) {
  return (binString.charCodeAt(0) << 24) + (binString.charCodeAt(1) << 16) +
    (binString.charCodeAt(2) << 8) + binString.charCodeAt(3);
};

如果没有按位运算,我怎么能做到这一点?谢谢!

【问题讨论】:

  • 您确实应该为该特定功能禁用这种无意义的 linting 规则。
  • 我假设您的函数对于第一个字符为 > \x7F 的输入字符串存在错误。如果您认为这是所需的行为,请告诉我们。见stackoverflow.com/a/37705109/1647737
  • @Bergi 向我们展示了这些规则究竟如何具有一些优点

标签: javascript bit-manipulation bitwise-operators


【解决方案1】:

您可以使用具有 2 个不同视图的 ArrayBuffer。使用Uint8Array 写入字节并使用DataView 读取一个值,指定大端序,如下所示:

stringAsUInt32BE(binString) {
    var buffer = new ArrayBuffer(4);
    var uint8View = new Uint8Array(buffer);
    uint8View[0] = binString.charCodeAt(0);
    uint8View[1] = binString.charCodeAt(1);
    uint8View[2] = binString.charCodeAt(2);
    uint8View[3] = binString.charCodeAt(3);
    return new DataView(buffer).getUint32(0, false); // false for big endian
}

当不支持类型化数组时,在旧浏览器上使用位操作会更好。

【讨论】:

    【解决方案2】:

    您可以将&lt;&lt; x 替换为* Math.pow(2, x)

    这两个语句之间的主要区别在于非常大或负输入x 的行为,例如位运算符将其操作数转换为二补数,而其他算术运算符则不会。

    // converts a four-character string into a big endian 32-bit unsigned integer
    function stringAsUInt32BE(binString) {
      return binString.charCodeAt(0) * 16777216 + binString.charCodeAt(1) * 65536 + binString.charCodeAt(2) * 256 + binString.charCodeAt(3);
    }
    
    console.log(stringAsUInt32BE('\xFF\xFF\xFF\xFF')); // 4294967295
    console.log(stringAsUInt32BE('\x00\x00\x00\x00')); // 0

    注意stringAsUInt32BE('\xFF\xFF\xFF\xFF') 的行为:您的原始函数将返回-1,我认为这是一个错误。这是因为'\xFF'.charCodeAt(0) &lt;&lt; 24 === 255 &lt;&lt; 24 超出了二补码的最大范围Math.pow(2, 32-1)-1,因此溢出到-16777216。此处给出的函数不会受到该转换问题的影响。

    【讨论】:

    • 第一个字符为 > \x7F 的字符串不会导致 -1。感谢您的洞察力!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多