Node.js net.isIP()実践プログラミング!IPアドレス検証サンプルコード集

2025-04-07

具体的な動作は以下の通りです。

  • 戻り値
    • 0: 与えられた文字列が有効なIPアドレスではない場合。
    • 4: 与えられた文字列が有効なIPv4アドレスである場合。
    • 6: 与えられた文字列が有効なIPv6アドレスである場合。
  • 引数
    net.isIP()は、IPアドレスとして評価する文字列を引数として受け取ります。

つまり、この関数は、与えられた文字列がIPアドレスの種類(IPv4またはIPv6)を特定し、その種類に応じた数値を返すことで、IPアドレスの有効性を確認します。

例を挙げると、以下のようになります。

const net = require('net');

console.log(net.isIP('127.0.0.1')); // 4 (IPv4)
console.log(net.isIP('2001:0db8:85a3:0000:0000:8a2e:0370:7334')); // 6 (IPv6)
console.log(net.isIP('invalid')); // 0 (無効)

この例では、net.isIP()関数を使用して、異なる文字列がIPアドレスとして有効かどうかを判定しています。



一般的なエラーとトラブルシューティング

    • 最も一般的なエラーは、net.isIP()に渡された文字列が有効なIPアドレスの形式に合致しない場合です。
    • 例: スペルミス、余分な文字、不完全なIPアドレスなど。
    • トラブルシューティング:
      • IPアドレス文字列を慎重に確認し、IPv4またはIPv6の正しい形式に従っていることを確認します。
      • 正規表現や他の検証方法を使用して、IPアドレスの形式を事前にチェックすることを検討します。
  1. 型のエラー

    • net.isIP()は文字列を引数として期待します。数値やオブジェクトなどの他のデータ型を渡すと、予期しない結果やエラーが発生する可能性があります。
    • トラブルシューティング:
      • net.isIP()に渡す前に、引数が文字列であることを確認します。
      • typeof演算子を使用し、変数の型を確認してください。
  2. IPv6の複雑さ

    • IPv6アドレスはIPv4アドレスよりも複雑な形式を持つため、間違いやすいです。
    • 例: 圧縮形式、ゾーン識別子など。
    • トラブルシューティング:
      • IPv6アドレスの正しい形式を理解し、特に圧縮形式やゾーン識別子を扱う場合は注意が必要です。
      • IPv6アドレスを扱うための専用のライブラリや関数を使用することを検討します。
  3. 期待される戻り値の誤解

    • net.isIP()はブール値ではなく、数値(0, 4, 6)を返します。この戻り値をブール値として使用すると、予期しない結果になる可能性があります。
    • トラブルシューティング:
      • 戻り値の解釈を正しく理解し、0, 4, 6のそれぞれの意味を把握します。
      • 戻り値を適切に比較して、IPアドレスの有効性を判定します。
  4. ネットワーク環境の変化

    • ネットワーク環境の変化(例えば、IPv6の有効化/無効化)によって、IPアドレスの検証結果が変わる可能性があります。
    • トラブルシューティング:
      • アプリケーションが実行されるネットワーク環境を考慮し、IPアドレスの検証が環境の変化に対応できるようにします。

コード例

const net = require('net');

function validateIP(ip) {
  const result = net.isIP(ip);
  if (result === 0) {
    console.log(`${ip} は無効なIPアドレスです。`);
  } else if (result === 4) {
    console.log(`${ip} は有効なIPv4アドレスです。`);
  } else if (result === 6) {
    console.log(`${ip} は有効なIPv6アドレスです。`);
  }
}

validateIP('127.0.0.1');
validateIP('2001:0db8:85a3:0000:0000:8a2e:0370:7334');
validateIP('invalid');
validateIP(1234); // 型のエラーが起こらないだけで、0が返ってくる。


例1: IPアドレスの検証と種類判定

この例では、ユーザーから与えられたIPアドレス文字列を検証し、それが有効なIPv4またはIPv6アドレスであるかどうかを判定します。

const net = require('net');
const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout,
});

readline.question('IPアドレスを入力してください: ', (ip) => {
  const result = net.isIP(ip);

  if (result === 0) {
    console.log(`${ip} は無効なIPアドレスです。`);
  } else if (result === 4) {
    console.log(`${ip} は有効なIPv4アドレスです。`);
  } else if (result === 6) {
    console.log(`${ip} は有効なIPv6アドレスです。`);
  }

  readline.close();
});

このコードでは、readlineモジュールを使用してユーザーからIPアドレスの入力を受け取り、net.isIP()で検証しています。検証結果に応じて、IPアドレスの有効性と種類をコンソールに出力します。

例2: IPアドレスの配列を検証する関数

この例では、IPアドレスの配列を受け取り、各IPアドレスの有効性を検証する関数を作成します。

const net = require('net');

function validateIPAddresses(ipAddresses) {
  ipAddresses.forEach((ip) => {
    const result = net.isIP(ip);

    if (result === 0) {
      console.log(`${ip} は無効なIPアドレスです。`);
    } else if (result === 4) {
      console.log(`${ip} は有効なIPv4アドレスです。`);
    } else if (result === 6) {
      console.log(`${ip} は有効なIPv6アドレスです。`);
    }
  });
}

const addresses = [
  '192.168.1.1',
  '2001:0db8:85a3::8a2e:0370:7334',
  'invalid_ip',
  '127.0.0.1',
];

validateIPAddresses(addresses);

このコードでは、validateIPAddresses関数がIPアドレスの配列を受け取り、forEachループで各IPアドレスを検証します。各IPアドレスの検証結果をコンソールに出力します。

const net = require('net');

function getIPVersion(ip) {
  const result = net.isIP(ip);

  if (result === 4) {
    return 'IPv4';
  } else if (result === 6) {
    return 'IPv6';
  } else {
    return '無効なIPアドレス';
  }
}

console.log(getIPVersion('192.168.1.1')); // IPv4
console.log(getIPVersion('2001:0db8:85a3::8a2e:0370:7334')); // IPv6
console.log(getIPVersion('invalid')); // 無効なIPアドレス


正規表現 (Regular Expressions) を使用する

正規表現は、特定のパターンに一致する文字列を検索するために使用されます。IPアドレスの形式を詳細に検証するために、正規表現を使用できます。

function isValidIPv4(ip) {
  const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
  if (!ipv4Regex.test(ip)) {
    return false;
  }

  const parts = ip.split('.').map(Number);
  return parts.every((part) => part >= 0 && part <= 255);
}

function isValidIPv6(ip) {
  const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(:[0-9a-fA-F]{1,4}){1,6}$|^:(:[0-9a-fA-F]{1,4}){1,7}$/;
  return ipv6Regex.test(ip);
}

function isValidIP(ip) {
  return isValidIPv4(ip) || isValidIPv6(ip);
}

console.log(isValidIP('192.168.1.1')); // true
console.log(isValidIP('2001:0db8:85a3::8a2e:0370:7334')); // true
console.log(isValidIP('invalid')); // false
  • 欠点
    正規表現は複雑になる可能性があり、可読性が低下することがあります。IPv6の検証は非常に複雑になります。
  • 利点
    正規表現は、IPアドレスの形式を細かく制御できます。

IPアドレス検証ライブラリを使用する

Node.jsのエコシステムには、IPアドレスの検証を容易にするためのライブラリがいくつか存在します。

const ipAddress = require('ip-address');

function isValidIPUsingLibrary(ip) {
  return ipAddress.Address4.isValid(ip) || ipAddress.Address6.isValid(ip);
}

console.log(isValidIPUsingLibrary('192.168.1.1')); // true
console.log(isValidIPUsingLibrary('2001:0db8:85a3::8a2e:0370:7334')); // true
console.log(isValidIPUsingLibrary('invalid')); // false
  • 欠点
    外部ライブラリを追加する必要があり、プロジェクトの依存関係が増えます。
  • 利点
    ライブラリは、複雑なIPアドレスの検証を簡素化し、高度な機能を提供します。

dns.lookup()を使用する

IPアドレスが有効かどうかを検証するだけでなく、そのIPアドレスが実際に解決できるかどうかを確認したい場合は、dns.lookup()を使用できます。

const dns = require('dns');

function isResolvableIP(ip, callback) {
  dns.lookup(ip, (err, address, family) => {
    if (err) {
      callback(false);
    } else {
      callback(true);
    }
  });
}

isResolvableIP('127.0.0.1', (result) => {
  console.log(`127.0.0.1 は解決可能ですか? ${result}`);
});

isResolvableIP('invalid', (result) => {
  console.log(`invalid は解決可能ですか? ${result}`);
});
  • 欠点
    DNSクエリが必要なため、時間がかかる場合があります。IPアドレスが解決できることと、IPアドレスが有効であることは別のことです。
  • 利点
    IPアドレスが実際に使用可能かどうかを確認できます。
  • 詳細な形式の制御
    正規表現を使用します。
  • IPアドレスの解決可能性の確認
    dns.lookup()を使用します。
  • 複雑なIPアドレスの検証や高度な操作
    ip-addressなどのライブラリを使用します。
  • 単純なIPアドレスの形式検証
    net.isIP()で十分です。