【问题标题】:How do I swap endian-ness (byte order) of a variable in javascript如何在javascript中交换变量的字节序(字节顺序)
【发布时间】:2011-07-16 06:44:07
【问题描述】:

我正在接收和发送两个小端数的十进制表示。我想:

  • 将一个变量左移 8 位
  • 或者他们
  • 移位可变位数
  • 创建 2 个 8 位数字,分别代表 16 位数字的前半部分和后半部分。

javascript(根据https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators)在移位时使用大端表示...

endianness 对我来说有点陌生(我只有 90% 确定我概述的步骤是我想要的。)所以交换有点令人眼花缭乱。请帮忙!我只需要知道如何以有效的方式交换订单。 (我只能想到在 toString() 返回值上使用 for 循环)

【问题讨论】:

    标签: javascript endianness


    【解决方案1】:

    这样的函数可以用来改变js中的字节顺序:

    const changeEndianness = (string) => {
            const result = [];
            let len = string.length - 2;
            while (len >= 0) {
              result.push(string.substr(len, 2));
              len -= 2;
            }
            return result.join('');
    }
    
    changeEndianness('AA00FF1234'); /// '3412FF00AA'
    

    【讨论】:

    • 使用字符串的工作很棒!
    【解决方案2】:
    function swap16(val) {
        return ((val & 0xFF) << 8)
               | ((val >> 8) & 0xFF);
    }
    

    解释:

    1. 假设val 是例如0xAABB
    2. 屏蔽val 以通过&amp;ing0xFF 获取LSB:结果为0xBB
    3. Shift 左边 8 位的结果:结果是 0xBB00
    4. Shift val 向右 8 位:结果为 0xAA(LSB 已“下降”到右侧)。
    5. 通过&amp;ing0xFF 屏蔽该结果以获取LSB:结果为0xAA
    6. 将第 3 步和第 5 步的结果通过|ing 组合在一起:
      0xBB00 | 0xAA0xBBAA

    function swap32(val) {
        return ((val & 0xFF) << 24)
               | ((val & 0xFF00) << 8)
               | ((val >> 8) & 0xFF00)
               | ((val >> 24) & 0xFF);
    }
    

    解释:

    1. 假设val0xAABBCCDD
    2. 掩码val 以通过&amp;ing0xFF 获得LSB:结果是0xDD
    3. Shift 左边 24 位的结果:结果是 0xDD000000
    4. 屏蔽val 以通过&amp;ing0xFF00 获取第二个字节:结果是0xCC00
    5. Shift 左边 8 位的结果:结果是 0xCC0000
    6. Shift val 向右 8 位:结果为 0xAABBCC(LSB 已“下降”到右侧)。
    7. &amp;ing0xFF00 屏蔽该结果以获取第二个字节:结果为0xBB00
    8. Shift val 向右 24 位:结果是 0xAA(除了 MSB 之外的所有内容都“掉”在了右侧)。
    9. 通过&amp;ing0xFF 屏蔽该结果以获取LSB:结果为0xAA
    10. |ing 将步骤 3、5、7 和 9 的结果组合在一起:
      0xDD000000 | 0xCC0000 | 0xBB00 | 0xAA0xDDCCBBAA

    【讨论】:

    • 所以,这似乎行得通...是否有一个简单的口头解释,还是我应该接受它并运行?
    • @griotspeak:我进行了编辑以尝试解释,尽管我怀疑您阅读维基百科上的 endiannessbitwise operations 文章会更有意义。
    • 好的,这实际上不是我想要的,但我想我只是不清楚。我需要前 8(或 16?)位的字面反转。我认为这个答案让我足够接近解决它。
    • function swap8(val) { return ((val &amp; 0x1) &lt;&lt; 7) | ((val &amp; 0x2) &lt;&lt; 5) | ((val &amp; 0x4) &lt;&lt; 3) | ((val &amp; 0x8) &lt;&lt; 1) | ((val &gt;&gt; 1) &amp; 0x8) | ((val &gt;&gt; 3) &amp; 0x4) | ((val &gt;&gt; 5) &amp; 0x2) | ((val &gt;&gt; 7) &amp; 0x1); } 是我的最终解决方案
    • @whiskeyspider 已经提到了符号问题。这就是我最终得到的结果:function swap16(val) { var x = ((val &amp; 0xFF) &lt;&lt; 8) | ((val &gt;&gt; 8) &amp; 0xFF); if (x &lt; 0) x = (x &amp; 0x7FFF) + 0x8000; return x; } function swap32(val) { var x = ((val &amp; 0xFF) &lt;&lt; 24) | ((val &amp; 0xFF00) &lt;&lt; 8) | ((val &gt;&gt; 8) &amp; 0xFF00) | ((val &gt;&gt; 24) &amp; 0xFF); if (x &lt; 0) x = (x &amp; 0x7FFFFFFF) + 0x80000000; return x; }
    【解决方案3】:

    使用

    我真的认为 JavaScript 的底层实现将使用它所运行的平台所使用的任何字节顺序。由于您无法在 JavaScript 中直接访问内存,因此您不必担心数字在内存中的物理表示方式。无论字节顺序如何,移位整数值总是产生相同的结果。只有在使用指针查看内存中的单个字节时,您才会看到差异。

    【讨论】:

    • 我确实得到了一个小端数的十进制表示,需要返回一个小端数的十进制表示。显示器是由二进制表示驱动的……所以这很重要。
    • 我想我明白你在说什么,而且我认为在很多情况下你是正确的。我得到和给出的数字是为了从左到右打开 8 个灯,所以我基本上会查看各个字节。
    猜你喜欢
    • 1970-01-01
    • 2021-08-07
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多