IP地址计算器

IPv4子网划分计算,支持CIDR表示法,快速计算网络地址、广播地址、主机范围等信息

📥 输入参数

function isValidIP(ip) { const parts = ip.split('.'); if (parts.length !== 4) return false; for (let part of parts) { const num = parseInt(part); if (isNaN(num) || num < 0 || num > 255 || part !== String(num)) return false; } return true; } function ipToLong(ip) { const parts = ip.split('.'); return ((parseInt(parts[0]) << 24) | (parseInt(parts[1]) << 16) | (parseInt(parts[2]) << 8) | parseInt(parts[3])) >>> 0; } function longToIp(long) { return [(long >>> 24) & 255, (long >>> 16) & 255, (long >>> 8) & 255, long & 255].join('.'); } function cidrToMask(cidr) { if (cidr === 0) return 0; return (~((1 << (32 - cidr)) - 1)) >>> 0; } function maskToCidr(mask) { let cidr = 0; let m = mask; while ((m & 1) === 0 && cidr < 32) { m >>>= 1; cidr++; } return 32 - cidr; } function maskToDotted(mask) { return longToIp(mask); } function toBinary(ip) { return ip.split('.').map(octet => parseInt(octet).toString(2).padStart(8, '0')).join('.'); } function calculate() { document.getElementById('errorMsg').textContent = ''; const ipStr = document.getElementById('ipInput').value.trim(); const maskStr = document.getElementById('maskInput').value.trim(); if (!isValidIP(ipStr)) { document.getElementById('errorMsg').textContent = '❌ 无效的IP地址格式'; return; } let cidr; let maskLong; if (maskStr.startsWith('/')) { cidr = parseInt(maskStr.substring(1)); if (isNaN(cidr) || cidr < 0 || cidr > 32) { document.getElementById('errorMsg').textContent = '❌ 无效的CIDR前缀 (0-32)'; return; } maskLong = cidrToMask(cidr); } else if (isValidIP(maskStr)) { maskLong = ipToLong(maskStr); // 验证是否是有效子网掩码 const binary = maskLong.toString(2).padStart(32, '0'); const zeroFound = binary.indexOf('0'); const oneAfterZero = zeroFound >= 0 ? binary.indexOf('1', zeroFound) : -1; if (oneAfterZero >= 0) { document.getElementById('errorMsg').textContent = '❌ 无效的子网掩码(非连续)'; return; } cidr = maskToCidr(maskLong); } else { document.getElementById('errorMsg').textContent = '❌ 无效的子网掩码格式,请使用如 255.255.255.0 或 /24'; return; } const ipLong = ipToLong(ipStr); const networkLong = (ipLong & maskLong) >>> 0; const broadcastLong = (networkLong | (~maskLong)) >>> 0; const firstHostLong = networkLong + 1; const lastHostLong = broadcastLong - 1; const totalHosts = Math.pow(2, 32 - cidr); const usableHosts = cidr <= 30 ? totalHosts - 2 : (cidr === 31 ? 2 : 1); const wildcardLong = (~maskLong) >>> 0; const ipClass = getIPClass(ipStr); const isPrivate = checkPrivate(ipStr); const ipType = getIPType(ipStr); const results = [ { label: 'IP地址', value: ipStr }, { label: '子网掩码', value: maskToDotted(maskLong) }, { label: 'CIDR前缀', value: '/' + cidr }, { label: '网络地址', value: longToIp(networkLong), copy: true }, { label: '广播地址', value: longToIp(broadcastLong), copy: true }, { label: '可用主机范围', value: cidr === 32 ? ipStr : (cidr === 31 ? `${longToIp(firstHostLong)} - ${longToIp(lastHostLong+1)}` : `${longToIp(firstHostLong)} - ${longToIp(lastHostLong)}`) }, { label: '总主机数', value: totalHosts.toLocaleString() }, { label: '可用主机数', value: usableHosts.toLocaleString() }, { label: '通配符掩码', value: longToIp(wildcardLong) }, { label: 'IP类别', value: ipClass }, { label: 'IP类型', value: isPrivate ? '私有地址' : '公有地址' }, { label: '特殊类型', value: ipType || '-' } ]; let gridHtml = ''; results.forEach(r => { gridHtml += `
${r.label}
${r.value}${r.copy ? '' : ''}
`; }); document.getElementById('resultGrid').innerHTML = gridHtml; document.getElementById('resultCard').style.display = 'block'; // 二进制信息 const ipBin = toBinary(ipStr); const maskBin = toBinary(maskToDotted(maskLong)); const netBin = toBinary(longToIp(networkLong)); const broadBin = toBinary(longToIp(broadcastLong)); document.getElementById('binaryInfo').innerHTML = `
IP地址 (二进制)
${ipBin}
子网掩码 (二进制)
${maskBin}
网络地址 (二进制)
${netBin}
广播地址 (二进制)
${broadBin}
`; document.getElementById('binaryCard').style.display = 'block'; // 子网表格 const tbody = document.querySelector('#subnetTable tbody'); tbody.innerHTML = ` IP地址${ipStr} 子网掩码${maskToDotted(maskLong)} CIDR表示法${longToIp(networkLong)}/${cidr} 网络地址${longToIp(networkLong)} 第一个可用主机${cidr === 32 ? '-' : (cidr === 31 ? longToIp(firstHostLong) : longToIp(firstHostLong))} 最后一个可用主机${cidr <= 30 ? longToIp(lastHostLong) : (cidr === 31 ? longToIp(lastHostLong+1) : '-')} 广播地址${cidr === 32 ? '-' : longToIp(broadcastLong)} 总IP数量${totalHosts.toLocaleString()} 可用主机数${usableHosts.toLocaleString()} IP类别${ipClass} 地址类型${isPrivate ? '私有' : '公有'} `; document.getElementById('subnetCard').style.display = 'block'; } function getIPClass(ip) { const first = parseInt(ip.split('.')[0]); if (first < 128) return 'A类 (1-126)'; if (first < 192) return 'B类 (128-191)'; if (first < 224) return 'C类 (192-223)'; if (first < 240) return 'D类 (组播 224-239)'; return 'E类 (保留 240-255)'; } function checkPrivate(ip) { const parts = ip.split('.').map(Number); if (parts[0] === 10) return true; if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true; if (parts[0] === 192 && parts[1] === 168) return true; if (parts[0] === 127) return true; return false; } function getIPType(ip) { const long = ipToLong(ip); if (long === ipToLong('0.0.0.0')) return '默认路由/本网络'; if (long === ipToLong('255.255.255.255')) return '受限广播'; const parts = ip.split('.').map(Number); if (parts[0] === 127) return '回环地址'; if (parts[0] >= 224 && parts[0] <= 239) return '组播地址'; if (parts[0] >= 240) return '保留地址'; if (ip.startsWith('169.254.')) return '链路本地地址'; return ''; } function copyText(text) { navigator.clipboard.writeText(text).then(() => alert('已复制: ' + text)); } // 回车触发计算 document.getElementById('ipInput').addEventListener('keypress', e => { if(e.key==='Enter') calculate(); }); document.getElementById('maskInput').addEventListener('keypress', e => { if(e.key==='Enter') calculate(); }); // 页面加载时自动计算一次 window.onload = calculate;