{"id":1925,"date":"2026-09-06T15:22:13","date_gmt":"2026-09-06T07:22:13","guid":{"rendered":"https:\/\/www.jumoon.top\/?p=1925"},"modified":"2026-09-06T17:17:41","modified_gmt":"2026-09-06T09:17:41","slug":"cidr-to-ip-%e8%bd%ac%e6%8d%a2%e5%99%a8","status":"publish","type":"post","link":"https:\/\/www.jumoon.top\/?p=1925","title":{"rendered":"CIDR to IP \u8f6c\u6362\u5668"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>CIDR \u8f6c IP \u5217\u8868\u8ba1\u7b97\u5668<\/title>\n<style>\n  * { margin: 0; padding: 0; box-sizing: border-box; }\n  body {\n    font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n    background: #f0f2f5;\n    min-height: 100vh;\n    padding: 24px;\n  }\n  .container { max-width: 800px; margin: 0 auto; }\n  h1 { text-align: center; color: #1a1a2e; margin-bottom: 24px; font-size: 24px; }\n  .card {\n    background: #fff; border-radius: 12px; padding: 24px;\n    box-shadow: 0 2px 12px rgba(0,0,0,0.08); margin-bottom: 20px;\n  }\n  .field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }\n  label { font-size: 13px; color: #555; font-weight: 500; }\n  input {\n    height: 40px; border: 1.5px solid #ddd; border-radius: 8px;\n    padding: 0 12px; font-size: 15px; transition: border-color .2s; outline: none; width: 100%;\n  }\n  input:focus { border-color: #4f6ef7; }\n  .btn {\n    height: 40px; padding: 0 24px; border: none; border-radius: 8px;\n    font-size: 15px; font-weight: 600; cursor: pointer; transition: background .2s, transform .1s;\n  }\n  .btn:active { transform: scale(0.97); }\n  .btn-primary { background: #4f6ef7; color: #fff; }\n  .btn-primary:hover { background: #3b5de7; }\n  .btn-success { background: #22c55e; color: #fff; }\n  .btn-success:hover { background: #16a34a; }\n  .btn-secondary { background: #e5e7eb; color: #374151; }\n  .btn-secondary:hover { background: #d1d5db; }\n  .actions { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }\n  .info-bar { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }\n  .tag {\n    background: #eff4ff; color: #4f6ef7; padding: 4px 12px;\n    border-radius: 20px; font-size: 13px; font-weight: 500;\n  }\n  .tag.green { background: #dcfce7; color: #166534; }\n  .tag.orange { background: #fef3c7; color: #92400e; }\n  .tag.blue { background: #dbeafe; color: #1e40af; }\n  #output {\n    width: 100%;\n    height: 400px;\n    border: 1.5px solid #e5e7eb;\n    border-radius: 8px;\n    padding: 12px;\n    font-size: 13px;\n    font-family: \"SF Mono\", Monaco, Consolas, monospace;\n    resize: vertical;\n    outline: none;\n    line-height: 1.8;\n    color: #333;\n    background: #fafafa;\n  }\n  #output:focus { border-color: #4f6ef7; background: #fff; }\n  .toast {\n    position: fixed; bottom: 32px; left: 50%;\n    transform: translateX(-50%) translateY(80px);\n    background: #1a1a2e; color: #fff; padding: 10px 24px;\n    border-radius: 8px; font-size: 14px; opacity: 0;\n    transition: all .3s; pointer-events: none; z-index: 999;\n  }\n  .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }\n  .error-msg { color: #ef4444; font-size: 13px; margin-top: 8px; display: none; white-space: pre-line; }\n  .checkbox-row {\n    display: flex; align-items: center; gap: 8px; margin-top: 10px;\n    font-size: 14px; color: #555;\n  }\n  .checkbox-row input[type=checkbox] { width: 18px; height: 18px; }\n  .hint { font-size: 12px; color: #999; margin-top: 4px; }\n  .summary-box {\n    background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px;\n    padding: 16px; font-size: 14px; line-height: 2; color: #334155;\n  }\n  .summary-box .label { color: #64748b; font-size: 12px; }\n  .summary-box .value { font-family: \"SF Mono\", Monaco, Consolas, monospace; font-weight: 600; }\n  @media (max-width: 500px) { .btn { width: 100%; } }\n<\/style>\n<\/head>\n<body>\n<div class=\"container\">\n  <h1>\ud83c\udf10 CIDR \u8f6c IP \u5217\u8868<\/h1>\n\n  <div class=\"card\">\n    <div class=\"field\">\n      <label>CIDR \u5730\u5740<\/label>\n      <input type=\"text\" id=\"cidrInput\" placeholder=\"\u4f8b\u5982\uff1a192.168.1.0\/24\" autocomplete=\"off\">\n      <div class=\"hint\">\u683c\u5f0f a.b.c.d\/n\uff0c\u6bcf\u6bb5 0-255\uff0c\u524d\u7f00 0-32 | \/16 \u53ca\u4ee5\u4e0b\u751f\u6210\u5217\u8868\uff0c\u66f4\u5927\u4ec5\u663e\u793a\u7edf\u8ba1<\/div>\n    <\/div>\n    <div class=\"checkbox-row\">\n      <input type=\"checkbox\" id=\"skipNetwork\">\n      <label for=\"skipNetwork\">\u8df3\u8fc7\u7f51\u7edc\u5730\u5740\uff08\u7b2c\u4e00\u4e2a IP\uff09<\/label>\n    <\/div>\n    <div class=\"checkbox-row\">\n      <input type=\"checkbox\" id=\"skipBroadcast\">\n      <label for=\"skipBroadcast\">\u8df3\u8fc7\u5e7f\u64ad\u5730\u5740\uff08\u6700\u540e\u4e00\u4e2a IP\uff09<\/label>\n    <\/div>\n    <div class=\"error-msg\" id=\"errorMsg\"><\/div>\n    <div style=\"margin-top:16px\">\n      <button class=\"btn btn-primary\" onclick=\"convert()\">\u751f\u6210<\/button>\n    <\/div>\n  <\/div>\n\n  <div class=\"card\" id=\"resultCard\" style=\"display:none\">\n    <div class=\"info-bar\" id=\"infoBar\"><\/div>\n    <div id=\"contentArea\"><\/div>\n    <div class=\"actions\" id=\"actionsBar\"><\/div>\n  <\/div>\n<\/div>\n\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<script>\nconst cidrInput = document.getElementById('cidrInput');\ncidrInput.addEventListener('keydown', e => { if (e.key === 'Enter') convert(); });\n\nfunction showToast(msg) {\n  const t = document.getElementById('toast');\n  t.textContent = msg;\n  t.classList.add('show');\n  setTimeout(() => t.classList.remove('show'), 2000);\n}\n\nfunction showError(msg) {\n  const el = document.getElementById('errorMsg');\n  el.textContent = msg;\n  el.style.display = 'block';\n}\nfunction hideError() { document.getElementById('errorMsg').style.display = 'none'; }\n\nfunction validateOctet(s) {\n  if (!\/^\\d{1,3}$\/.test(s)) return null;\n  const v = parseInt(s, 10);\n  return (v >= 0 && v <= 255) ? v : null;\n}\n\nfunction parseCIDR(raw) {\n  const m = raw.match(\/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\\/(\\d{1,2})$\/);\n  if (!m) return null;\n  const nums = [m[1], m[2], m[3], m[4]].map(validateOctet);\n  if (nums.some(n => n === null)) return null;\n  const prefix = parseInt(m[5], 10);\n  if (prefix > 32) return null;\n  if (prefix <= 1) {\n    return { error: '\u524d\u7f00 \/' + prefix + ' \u8986\u76d6\u7ea6 ' + Math.pow(2, 31).toLocaleString() + ' \u4e2aIP\uff0c\u89c4\u6a21\u8fc7\u5927\uff0c\u65e0\u5b9e\u9645\u610f\u4e49' };\n  }\n  const addrInt = ((nums[0] << 24) | (nums[1] << 16) | (nums[2] << 8) | nums[3]) >>> 0;\n  const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n  const network = addrInt & mask;\n  const total = Math.pow(2, 32 - prefix);\n  const broadcast = network + total - 1;\n  return { network, prefix, total, broadcast };\n}\n\nfunction numToIp(n) {\n  return [(n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255].join('.');\n}\n\nfunction fmtNum(n) {\n  return n.toLocaleString('en-US');\n}\n\nconst MAX_LIST_COUNT = 65536;\n\nfunction convert() {\n  hideError();\n  const raw = cidrInput.value.trim();\n  const parsed = parseCIDR(raw);\n  if (!parsed) {\n    showError('\u683c\u5f0f\u9519\u8bef\uff1a\u8bf7\u4f7f\u7528 a.b.c.d\/n \u683c\u5f0f\\n\u6bcf\u6bb5 0-255\uff0c\u524d\u7f00 0-32\\n\u793a\u4f8b\uff1a192.168.1.0\/24');\n    return;\n  }\n  if (parsed.error) {\n    showError(parsed.error);\n    return;\n  }\n  const { network, prefix, total, broadcast } = parsed;\n  const hostBits = 32 - prefix;\n  const skipNet = document.getElementById('skipNetwork').checked;\n  const skipBc = document.getElementById('skipBroadcast').checked;\n  const start = skipNet ? 1 : 0;\n  const end = skipBc ? total - 2 : total - 1;\n  const count = Math.max(0, end - start + 1);\n  if (count <= 0) {\n    showError('\u8be5 CIDR \u65e0\u53ef\u7528\u4e3b\u673a IP\\n\uff08\/32 \u4ec5\u4e00\u4e2a\u5730\u5740\uff0c\/31 \u4e3a\u70b9\u5bf9\u70b9\u94fe\u8def\uff09');\n    return;\n  }\n  const cidrStr = numToIp(network) + '\/' + prefix;\n  document.getElementById('infoBar').innerHTML =\n    `<span class=\"tag\">${cidrStr}<\/span>` +\n    `<span class=\"tag green\">${fmtNum(count)} \u4e2a IP<\/span>` +\n    `<span class=\"tag blue\">\u7f51\u7edc\uff1a${numToIp(network)}<\/span>` +\n    `<span class=\"tag orange\">\u5e7f\u64ad\uff1a${numToIp(broadcast)}<\/span>`;\n\n  const contentArea = document.getElementById('contentArea');\n  const actionsBar = document.getElementById('actionsBar');\n\n  if (count > MAX_LIST_COUNT) {\n    contentArea.innerHTML = `\n      <div class=\"summary-box\">\n        <div><span class=\"label\">CIDR\uff1a<\/span><span class=\"value\">${cidrStr}<\/span><\/div>\n        <div><span class=\"label\">\u7f51\u7edc\u5730\u5740\uff1a<\/span><span class=\"value\">${numToIp(network)}<\/span><\/div>\n        <div><span class=\"label\">\u5e7f\u64ad\u5730\u5740\uff1a<\/span><span class=\"value\">${numToIp(broadcast)}<\/span><\/div>\n        <div><span class=\"label\">\u53ef\u7528 IP \u603b\u6570\uff1a<\/span><span class=\"value\">${fmtNum(count)}<\/span><\/div>\n        <div><span class=\"label\">\u4e3b\u673a\u4f4d\u6570\uff1a<\/span><span class=\"value\">${hostBits} \u4f4d\uff08\u5171 ${fmtNum(total)} \u4e2a\u5730\u5740\uff09<\/span><\/div>\n        <div style=\"margin-top:12px; color:#94a3b8; font-size:12px\">\n          \u26a0\ufe0f IP \u6570\u91cf\u8d85\u8fc7 ${fmtNum(MAX_LIST_COUNT)}\uff0c\u65e0\u6cd5\u751f\u6210\u5b8c\u6574\u5217\u8868\u3002\u8bf7\u7f29\u5c0f CIDR \u8303\u56f4\uff08\u5efa\u8bae \/16 \u53ca\u4ee5\u4e0b\uff09\u540e\u91cd\u8bd5\u3002\n        <\/div>\n      <\/div>`;\n    actionsBar.innerHTML = '';\n  } else {\n    const list = [];\n    for (let i = start; i <= end; i++) {\n      list.push(numToIp((network + i) >>> 0));\n    }\n    contentArea.innerHTML = `<textarea id=\"output\" readonly>${list.join('\\n')}<\/textarea>`;\n    actionsBar.innerHTML = `\n      <button class=\"btn btn-success\" id=\"btnCopy\" onclick=\"copyFn(this)\">\ud83d\udccb \u590d\u5236<\/button>\n      <button class=\"btn btn-secondary\" id=\"btnTxt\" onclick=\"dlFn(this,'txt')\">\u2b07 \u4e0b\u8f7d TXT<\/button>\n      <button class=\"btn btn-secondary\" id=\"btnCsv\" onclick=\"dlFn(this,'csv')\">\u2b07 \u4e0b\u8f7d CSV<\/button>`;\n  }\n  document.getElementById('resultCard').style.display = 'block';\n  document.getElementById('resultCard').scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n}\n\nfunction setBtnState(btn, text) {\n  const orig = btn.textContent;\n  btn.textContent = text;\n  btn.disabled = true;\n  setTimeout(() => { btn.textContent = orig; btn.disabled = false; }, 3000);\n}\n\nfunction copyFn(btn) {\n  const val = document.getElementById('output').value;\n  navigator.clipboard.writeText(val).then(() => setBtnState(btn, '\u2705 \u590d\u5236\u6210\u529f'));\n}\n\nfunction dlFn(btn, fmt) {\n  const val = document.getElementById('output').value;\n  const cidrRaw = cidrInput.value.trim();\n  let content = '', ext = fmt;\n  if (fmt === 'csv') {\n    let csv = '\u5e8f\u53f7,IP\u5730\u5740\\n';\n    val.split('\\n').forEach((ip, i) => { csv += `${i + 1},${ip}\\n`; });\n    content = csv;\n  } else {\n    content = val;\n  }\n  const blob = new Blob([content], { type: 'text\/plain;charset=utf-8' });\n  const url = URL.createObjectURL(blob);\n  const a = document.createElement('a');\n  a.href = url;\n  a.download = `${cidrRaw.replace(\/\\\/\/g, '_')}.${ext}`;\n  document.body.appendChild(a);\n  a.click();\n  document.body.removeChild(a);\n  setTimeout(() => URL.revokeObjectURL(url), 100);\n  setBtnState(btn, '\u2705 \u4e0b\u8f7d\u6210\u529f');\n}\n<\/script>\n<\/body>\n<\/html>\n\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>CIDR \u8f6c IP \u5217\u8868\u8ba1\u7b97\u5668 \ud83c\udf10 CIDR \u8f6c IP \u5217\u8868 CIDR \u5730\u5740 \u683c\u5f0f a.b.c.d\/n\uff0c\u6bcf\u6bb5  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","site-transparent-header":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[41,19],"tags":[],"class_list":["post-1925","post","type-post","status-publish","format-standard","hentry","category-41","category-19"],"_links":{"self":[{"href":"https:\/\/www.jumoon.top\/index.php?rest_route=\/wp\/v2\/posts\/1925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jumoon.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jumoon.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jumoon.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jumoon.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1925"}],"version-history":[{"count":17,"href":"https:\/\/www.jumoon.top\/index.php?rest_route=\/wp\/v2\/posts\/1925\/revisions"}],"predecessor-version":[{"id":1954,"href":"https:\/\/www.jumoon.top\/index.php?rest_route=\/wp\/v2\/posts\/1925\/revisions\/1954"}],"wp:attachment":[{"href":"https:\/\/www.jumoon.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jumoon.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jumoon.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}