JavaScriptで2つのIPアドレス間に存在するアドレス数を求める方法
問題
2つのIPv4アドレスを引数として受け取り、その間に存在するIPアドレスの総数を返すJavaScript関数を作成します。ここでいう「間」とは、最初のアドレスを含み、最後のアドレスは含まない範囲を指します。
IPv4アドレスは「0〜255の数値(オクテット)」を4つドットでつないだ構造になっており、各オクテットは256進法の1桁とみなすことができます。そのため、IPアドレス全体を1つの10進数に変換し、両者の差の絶対値を求めれば、間に存在するアドレス数を簡単に計算できます。
考え方:オクテットごとの重み
各オクテットには、左から順に次の重みが対応します。
- 第1オクテット:2563(16,777,216)
- 第2オクテット:2562(65,536)
- 第3オクテット:2561(256)
- 第4オクテット:2560(1)
この重みを各オクテットの差に掛けて合計することで、2つのIPアドレスの距離を1回のループで求められます。
コード例
const ip1 = '20.0.0.10';
const ip2 = '20.0.1.0';
const countIp = (ip1, ip2) => {
let diff = 0;
const aIp1 = ip1.split('.');
const aIp2 = ip2.split('.');
// オクテットは4つである必要がある
if (aIp1.length !== 4 || aIp2.length !== 4) {
return '無効なIPアドレス: フォーマットが不正です';
}
for (let x = 0; x < 4; x++) {
const n1 = Number(aIp1[x]);
const n2 = Number(aIp2[x]);
// 各オクテットは数値で、0〜255の範囲内である必要がある
if (
Number.isNaN(n1) || Number.isNaN(n2) ||
n1 < 0 || n1 > 255 ||
n2 < 0 || n2 > 255
) {
return '無効なIPアドレス: 値が不正です';
}
// 256の累乗の重みを掛けて差分を累積
diff += (n1 - n2) * 256 ** (3 - x);
}
return Math.abs(diff);
};
console.log(countIp(ip1, ip2));実行結果
246
コードの解説
- フォーマットのチェック: split('.')で文字列を分割し、オクテットがちょうど4つあることを確認します。4つ以外の場合は不正な形式としてエラーメッセージを返します。
- 値のチェック: 各オクテットが数値として解釈でき、かつ0〜255の範囲内であることを確認します。IPv4の各オクテットは8ビットで表現されるため、この範囲外の値は無効です。
- 差分の計算: 各オクテットの差に256の累乗の重みを掛けて合計し、最後にMath.abs()で絶対値を返します。これにより、引数を渡す順序(どちらのアドレスが大きいか)に左右されず、常に正の個数を取得できます。
この例では「20.0.0.10」と「20.0.1.0」を比較しています。第3オクテットの差は1(256アドレス分)、第4オクテットの差は逆方向に10であるため、実際の差は 256 − 10 = 246 となり、これが求めるアドレス数です。
まとめ
IPアドレスを文字列のまま比較すると、桁の重みが考慮されず誤った結果になる恐れがあります。各オクテットを256進法の桁として10進数に変換してから差を求めることで、正確かつ効率的にアドレス数をカウントできます。ログ解析やアクセス制御、IPレンジの集計など、さまざまな場面で応用できるテクニックなので、ぜひ覚えておきましょう。
-
JavaScriptで2つの配列間の欠落した数値を見つける方法
問題の概要 2つの配列 arr1 と arr2 を引数として受け取るJavaScript関数を作成します。 arr2 は arr1 の要素をシャッフルした複製ですが、たった1つの要素だけが欠落しています。 この関数の目的は、その欠落している1つの要素を見つけ出して返すことです。 アプローチのポイント 最もシンプルかつ効率的なのは、ハッシュマップ(オブジェクト)を使って各数値の出現回数を記録する方法です。計算量は O(n) に抑えられ、配列内に重複した値が含まれていても正しく動作します。 コード例 以下が実際のコードです。 const arr1 = [6, 1, 3, 6, 8, 2];
-
JavaScriptで0からnまで数えるときに「9」が出現する回数を数える方法
問題 数値 n を引数として受け取るJavaScript関数を作成します。この関数は、0からnまで順番に数えていく過程で、数字の「9」が何回登場するかを数え、その合計回数を返す必要があります。 解決のアプローチ この問題は、次の手順でシンプルに解決できます。 0からnまでの各数値を文字列に変換する 変換した文字列の中に「9」が何文字含まれているかを調べる すべての数値分のカウントを合計して返す 文字列内の特定の文字を数えるには、split() で1文字ずつ分解し、reduce() を使って一致する文字をカウントする方法が有効です。 コード例 以下が実際のコードです。 const num