こうこく
作 ▸
改 ▸

JavaScriptでバイトの左からnビット目を抽出する

バイナリいじってて使った

もくじ

バイトの左からnビット目を1桁抽出

/**
 * バイトの左からnビット目を1桁抽出して返却
 * @param  {Number} b - バイト (0~255)
 * @param  {Number} n - 左からn番目 (1~8)
 * @return {Number} 0 or 1
 */
const extractBit = (b, n) => {
	if (b < 0 || 255 < b) {
		throw new RangeError('値は0~255の範囲内で指定してください。');
	}
	if (n < 1 || 8 < n) {
		throw new RangeError('位置は1~8番目の範囲内で指定してください。');
	}
	const c = 8 - n;
	return (b & (1 << c)) >> c;
};
通ったテスト
console.assert( extractBit(0b00000001, 1) === 0 );
console.assert( extractBit(0b00000001, 2) === 0 );
console.assert( extractBit(0b00000001, 3) === 0 );
console.assert( extractBit(0b00000001, 4) === 0 );
console.assert( extractBit(0b00000001, 5) === 0 );
console.assert( extractBit(0b00000001, 6) === 0 );
console.assert( extractBit(0b00000001, 7) === 0 );
console.assert( extractBit(0b00000001, 8) === 1 );
console.assert( extractBit(0b10000000, 1) === 1 );
console.assert( extractBit(0b10000000, 2) === 0 );
console.assert( extractBit(0b10000000, 3) === 0 );
console.assert( extractBit(0b10000000, 4) === 0 );
console.assert( extractBit(0b10000000, 5) === 0 );
console.assert( extractBit(0b10000000, 6) === 0 );
console.assert( extractBit(0b10000000, 7) === 0 );
console.assert( extractBit(0b10000000, 8) === 0 );
console.assert( extractBit(0b01111110, 1) === 0 );
console.assert( extractBit(0b01111110, 2) === 1 );
console.assert( extractBit(0b01111110, 3) === 1 );
console.assert( extractBit(0b01111110, 4) === 1 );
console.assert( extractBit(0b01111110, 5) === 1 );
console.assert( extractBit(0b01111110, 6) === 1 );
console.assert( extractBit(0b01111110, 7) === 1 );
console.assert( extractBit(0b01111110, 8) === 0 );

バイトの左からnビット目をlen桁まで抽出

/**
 * バイトの左からnビット目をlen桁まで抽出して返却
 * @param  {Number} b - バイト (0~255)
 * @param  {Number} n - 左からn番目 (1~8)
 * @param  {Number} len - 長さ
 * @return {Number} 0~255
 */
const extractBits = (b, n, len = 1) => {
	if (b < 0 || 255 < b) {
		throw new RangeError('値は0~255の範囲内で指定してください。');
	}
	if (n < 1 || 8 < n) {
		throw new RangeError('位置は1~8番目の範囲内で指定してください。');
	}
	if (len < 0 || 8 < (len - 1 + n)) {
		throw new RangeError('長さがバイトをはみ出してます。');
	}
	let sum = 0;
	for (let i = 0; i < len; ++i) {
		const c = 8 - (n + i);
		sum += ((b & (1 << c)) >> c) << (len - i - 1);
	}
	return sum;
};
通ったテスト
// 長さ指定なし
console.assert( extractBits(0b00000001, 7) === 0 );
console.assert( extractBits(0b00000001, 8) === 1 );
console.assert( extractBits(0b10000000, 1) === 1 );
console.assert( extractBits(0b10000000, 2) === 0 );
console.assert( extractBits(0b01111110, 1) === 0 );
console.assert( extractBits(0b01111110, 2) === 1 );
console.assert( extractBits(0b01111110, 7) === 1 );
console.assert( extractBits(0b01111110, 8) === 0 );

// 長さ指定あり
console.assert( extractBits(0b00110011, 1, 2) === 0b00 );
console.assert( extractBits(0b00110011, 2, 2) === 0b01 );
console.assert( extractBits(0b00110011, 3, 2) === 0b11 );
console.assert( extractBits(0b00110011, 4, 2) === 0b10 );
console.assert( extractBits(0b00110011, 5, 2) === 0b00 );
console.assert( extractBits(0b00110011, 6, 2) === 0b01 );
console.assert( extractBits(0b00110011, 7, 2) === 0b11 );
try {
	console.assert( extractBits(0b00110011, 7, 2) === false );
} catch (e) {
	console.assert( e.message === '長さがバイトをはみ出してます。' );
}
この記事に何かあればこちらまで (非公開)