了解将大端转换为/从字符串转换

时间:2018-01-09 04:30:20

标签: javascript string bit-manipulation

看看这些实现,我想知道是否可以解释具体操作背后的原因。不是来自计算机科学,我不确定为什么做出这些决定。

function binb2rstr(input) {
  var str = []
  for (var i = 0, n = input.length * 32; i < n; i += 8) {
    var code = (input[i >> 5] >>> (24 - i % 32)) & 0xFF
    var val = String.fromCharCode(code)
    str.push(val)
  }
  return str.join('')
}

function rstr2binb(input) {
  var output = Array(input.length >> 2)

  for (var i = 0, n = output.length; i < n; i++) {
    output[i] = 0
  }

  for (var i = 0, n = input.length * 8; i < n; i += 8) {
    output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32)
  }

  return output
}

到目前为止我所理解的是:

  1. i += 8用于迭代字节。
  2. 0xFF为255,即2^8 - 1,因此为1个字节。
  3. 32,它是的大小,或4字节
  4. |是按位OR,<<>>>&同样是位运算符。
  5. %模数将值保持在x = x % max的最大值。
  6. 我不明白的是:

    1. i >> 5,如何选择。
    2. & 0xFF,如何选择。
    3. 24 - i % 32,24来自。
    4. var code = (input[i >> 5] >>> (24 - i % 32)) & 0xFF,如何从中计算字符代码。
    5. input.length >> 2
    6. 想知道这是否只是一个标准的计算机科学功能,因为很难分辨这些变量来自何处以及如何学习这些变量。看起来这些值必须是基于字节长度的标准算法,但我无法告诉如何使用这些开放式问题。谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

这段代码包含一些非常聪明的基于32位值的比特 但是,让我们按照你的观点开展工作:

  
      
  1. i&gt;&gt; 5,如何选择。
  2.   

这将i除以32 ---对应于n = input.length * 32总长度。考虑整个算法,这意味着在选择下一个(0,8,16,24)值之前,会将一个值处理input四次。

  
      
  1. &安培; 0xFF,如何选择。
  2.   

这只是选择n位值的最低8位。

  
      
  1. 24 - i%32,其中24来自。
  2.   

这与i += 8有关。 i % 32表示四个不同的迭代(32/8 = 4),即temp= (0, 8, 16, 24)。因此24-temp会产生(24,16,8,0)

  
      
  1. var code =(输入[i>&gt;&gt; 5]&gt;&gt;&gt;(24 - i%32))&amp; 0xFF,如何从中计算字符代码。
  2.   
1. 1st iteration: i=0 ;24-0=24; input[0] >>> 24 & 0xFF =     highest byte of input[0] shifted to lowest
2. 2nd iteration: i=8 ;24-8=16; input[0] >>> 16 & 0xFF = 2nd highest byte of input[0] shifted to 2nd lowest
3. 3rd iteration: i=16;24-16=8; input[0] >>>  8 & 0xFF = 2nd lowest  byte of input[0] shifted to 2nd highest
4. 4th iteration: i=8 ;24-24=0; input[0] >>>  0 & 0xFF =     lowest  byte of input[0] shifted to highest

这是Big-Endian-Conversion 下一次迭代有i=32并开始下一次迭代input[32/32] = input[1]

总体而言,该算法将32位代码向右移动,并屏蔽最低的8位,以便String.fromCharCode(code)用作CharCode。

最后一个是来自不同的算法,所以input.length >> 2只需要division by 2丢弃剩下的1个。

关于你的上一个问题:

  

似乎这些值必须是基于字节长度的标准算法,但我无法告诉如何使用这些开放式问题来实现这些目标。

这远非标准算法。它只是一个基于字节的聪明的位操作

在汇编程序中,这段代码更容易理解 甚至有一条名为BSWAP的指令在寄存器中的32位Big-Endian和Little-Endian值之间进行交换。