#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 бита), поэтому они тоже не имеют значения.