← 中文资源

简体中文版本

IPv4 地址校验与分类

严格解析点分十进制 IPv4,拒绝前导零,并识别私有、回环与链路本地地址段。

阅读英文原文

功能说明

parseIPv4 把点分十进制地址解析为四个 0 到 255 的整数,格式不合法时返回 null;isValidIPv4 提供布尔判断;isPrivateIPv4 识别 RFC 1918 私有段、回环段和 169.254 链路本地段。适合表单校验、访问控制名单、日志清洗和配置检查,能避免把 01.2.3.4 或 256.1.1.1 当成合法地址。

关键代码

解析器要求恰好四段、每段一到三位数字,并显式拒绝长度大于一且以零开头的段,因为不同系统对前导零可能解释为八进制,存在绕过风险。数值上限为 255。分类函数复用解析结果,按第一段和第二段判断 10/8、172.16/12、192.168/16、127/8 与 169.254/16,避免用字符串前缀匹配造成 192.1680 之类的误判。

使用注意

该函数只接受 IPv4,不接受 IPv4 映射的 IPv6、主机名、端口或 CIDR 后缀,调用前应剥离端口与空格。返回 null 而不是抛错是本模块的约定,调用方需区分格式错误与私有地址两种情况。私有地址判断不能替代完整的网络边界校验,公网服务还应结合代理头可信链与 CIDR 匹配。前导零策略偏严格,是安全优先的选择。

验证方式

测试 0.0.0.0、255.255.255.255、10.0.0.1、172.16.0.1、172.31.255.255、192.168.1.1、127.0.0.1 与 169.254.1.1。构造 256.1.1.1、1.2.3、1.2.3.4.5、01.2.3.4、空段、空格和含字母的输入,确认解析返回 null。最后测试非字符串输入与分类函数在非法地址上的返回值。

代码示例

export function parseIPv4(address) {
  if (typeof address !== "string") return null;
  const parts = address.split(".");
  if (parts.length !== 4) return null;
  const octets = [];
  for (const part of parts) {
    if (!/^\d{1,3}$/.test(part)) return null;
    if (part.length > 1 && part.startsWith("0")) return null;
    const value = Number(part);
    if (value > 255) return null;
    octets.push(value);
  }
  return octets;
}

export function isValidIPv4(address) {
  return parseIPv4(address) !== null;
}

export function isPrivateIPv4(address) {
  const octets = parseIPv4(address);
  if (!octets) return false;
  const [a, b] = octets;
  return a === 10
    || (a === 172 && b >= 16 && b <= 31)
    || (a === 192 && b === 168)
    || a === 127
    || (a === 169 && b === 254);
}