base64ArrayBuffer: зачем использовать маску для извлечения первой части фрагмента?

#javascript #bitmask

#javascript #битовая маска

Вопрос:

В приведенном ниже коде мы могли бы просто написать :

a = chunk >> 18 // 16515072 = (2^6 - 1) << 18

вместо :

a = (chunk amp; 16515072) >> 18 // 16515072 = (2^6 - 1) << 18

Я не вижу смысла использовать маску, так как мы хотим извлечь первую часть слева от фрагмента.

источник: введите описание ссылки здесь

 function base64ArrayBuffer(arrayBuffer) {
  var base64    = ''
  var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /'

  var bytes         = new Uint8Array(arrayBuffer)
  var byteLength    = bytes.byteLength
  var byteRemainder = byteLength % 3
  var mainLength    = byteLength - byteRemainder

  var a, b, c, d
  var chunk

  // Main loop deals with bytes in chunks of 3
  for (var i = 0; i < mainLength; i = i   3) {
    // Combine the three bytes into a single integer
    chunk = (bytes[i] << 16) | (bytes[i   1] << 8) | bytes[i   2]

    // Use bitmasks to extract 6-bit segments from the triplet
    a = (chunk amp; 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
    b = (chunk amp; 258048)   >> 12 // 258048   = (2^6 - 1) << 12
    c = (chunk amp; 4032)     >>  6 // 4032     = (2^6 - 1) << 6
    d = chunk amp; 63               // 63       = 2^6 - 1

    // Convert the raw binary segments to the appropriate ASCII encoding
    base64  = encodings[a]   encodings[b]   encodings[c]   encodings[d]
  }

  // Deal with the remaining bytes and padding
  if (byteRemainder == 1) {
    chunk = bytes[mainLength]

    a = (chunk amp; 252) >> 2 // 252 = (2^6 - 1) << 2

    // Set the 4 least significant bits to zero
    b = (chunk amp; 3)   << 4 // 3   = 2^2 - 1

    base64  = encodings[a]   encodings[b]   '=='
  } else if (byteRemainder == 2) {
    chunk = (bytes[mainLength] << 8) | bytes[mainLength   1]

    a = (chunk amp; 64512) >> 10 // 64512 = (2^6 - 1) << 10
    b = (chunk amp; 1008)  >>  4 // 1008  = (2^6 - 1) << 4

    // Set the 2 least significant bits to zero
    c = (chunk amp; 15)    <<  2 // 15    = 2^4 - 1

    base64  = encodings[a]   encodings[b]   encodings[c]   '='
  }

  return base64
}
 

Комментарии:

1. Да, это кажется ненужным. Самые левые 8 бит не используются и всегда равны нулю, правые биты >> 18 в любом случае стираются.

2. @ASDFGerte Самые левые 6 бит могут отличаться от 0. Тем не менее, я согласен с тем фактом, что правые биты стираются >> 18, вот почему я спрашивал. Спасибо за ваш комментарий.

3. Говоря о побитовых операциях в javascript, я говорю о 32-битных значениях. Самый левый 8-битный (с 25-го по 32-й бит) здесь всегда должен быть равен нулю.

4. @ASDFGerte В этой функции полный фрагмент составляет 3 октета (24 бита), который разбивается на 4 части по 6 бит. 6 бит первой части могут быть равны 1. Возможно, я не понимаю, что вы говорите.

5. Битовая маска есть 00000000111111000000000000000000 . Чтобы это было бесполезно, обе нулевые группы должны быть неактуальными. Правая сторона смещена, левая сторона (самая левая 8 бит) всегда равна нулю (base64 работает с трехбайтовыми группами, всего 24 бита), поэтому они тоже не имеют значения.