File manager - Edit - /home/kridsana/webapp.cm.in.th/663012801/u66301280015/สอบ IP/VLSM3.html
Back
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>VLSM Hierarchical Calculator</title> <style> body{ font-family:Segoe UI,Arial; background:#f1f3f6; padding:20px; } .dark{ background:#1e1e1e; color:#eee; } .header{ background:#1e293b; color:white; padding:15px; border-radius:8px; margin-bottom:15px; } .controls{ margin-bottom:15px; } input,select,button{ padding:8px; margin:5px; font-size:14px; } button{ cursor:pointer; } .summary{ background:white; padding:12px; border-radius:8px; margin-top:10px; } .dark .summary{ background:#2d2d2d; } /* TABLE */ table{ border-collapse:collapse; width:100%; margin-top:20px; background:white; } .dark table{ background:#2d2d2d; } th,td{ border:1px solid #ccc; padding:7px; text-align:left; } /* STICKY HEADER */ th{ position:sticky; top:200px; z-index:50; background:#333; color:white; box-shadow:0 2px 5px rgba(0,0,0,0.3); } thead th{ position: sticky; top: 0; background: #000; z-index: 999; } .dark th{ background:#111; } /* HOVER */ tr:hover{ background:#fff3cd !important; } .dark tr:hover{ background:#444 !important; } /* BINARY */ .binary{ font-family:Consolas,monospace; font-size:13px; } .bit-added{ color:red; font-weight:bold; } /* COLUMN COLORS */ td:nth-child(1){ background:#e8f5e9; } td:nth-child(3){ background:#e3f2fd; } td:nth-child(4){ background:#f3e5f5; } td:nth-child(5){ background:#e0f2f1; } td:nth-child(6){ background:#fff3e0; } /* DARK MODE COLUMN */ .dark td{ color:#eee; } .dark td:nth-child(1){ background:#2f3f33; } .dark td:nth-child(3){ background:#2b3c4a; } .dark td:nth-child(4){ background:#3a2f40; } .dark td:nth-child(5){ background:#2c3f3a; } .dark td:nth-child(6){ background:#4a3a2a; } /* RESERVED */ .reserved td{ background:#ff3b3b !important; color:white !important; font-weight:bold; } .dark input{ background:#444; color:white; border:1px solid #666; } .dark select{ background:#444; color:white; border:1px solid #666; } .copybtn{ padding:3px 6px; font-size:12px; } .warning{ color:red; margin-top:5px; } .copybtn{ margin-left:5px; } </style> </head> <body> <div class="header"> <h2>VLSM Hierarchical Calculator</h2> </div> <div class="controls"> Network Address <input type="text" id="baseIp" value="192.168.80.0"> Subnet Mask <select id="basePrefix"></select> <button onclick="initNetwork()">Start</button> <button onclick="toggleDark()">🌙 Dark</button> <button onclick="resetNetwork()">Reset</button> <div id="warning" class="warning"></div> <div id="networkSummary" class="summary"></div> </div> <div id="output"></div> <script> function ipToInt(ip){ return ip.split('.').reduce((a,b)=>(a<<8)+parseInt(b),0)>>>0; } function intToIp(int){ return [(int>>>24)&255,(int>>>16)&255,(int>>>8)&255,int&255].join('.'); } function prefixToMask(prefix){ let mask=(0xffffffff<<(32-prefix))>>>0; return intToIp(mask); } function usableHosts(prefix){ return (2**(32-prefix))-2; } function isValidIp(ip){ let parts=ip.split("."); if(parts.length!==4) return false; for(let p of parts){ let n=parseInt(p); if(isNaN(n)||n<0||n>255) return false; } return true; } function getNetworkAddress(ip,prefix){ let ipInt=ipToInt(ip); let mask=(0xffffffff<<(32-prefix))>>>0; let networkInt=ipInt & mask; return intToIp(networkInt); } function networkBinaryWithHighlight(network,prefix,parentPrefix){ let binary=ipToInt(network).toString(2).padStart(32,'0'); let result=""; for(let i=0;i<32;i++){ if(parentPrefix!==null && i>=parentPrefix && i<prefix) result+=`<span class="bit-added">${binary[i]}</span>`; else result+=binary[i]; if((i+1)%8===0 && i!==31) result+="."; } return result; } function subnetInfo(network,prefix){ let base=ipToInt(network); let size=2**(32-prefix); return{ network:network+"/"+prefix, mask:prefixToMask(prefix), first:intToIp(base+1), last:intToIp(base+size-2), broadcast:intToIp(base+size-1), hosts:size-2 }; } function splitSubnet(network,prefix,newPrefix){ let base=ipToInt(network); let size=2**(32-newPrefix); let count=2**(newPrefix-prefix); let arr=[]; for(let i=0;i<count;i++){ arr.push({ network:intToIp(base+i*size), prefix:newPrefix, parentPrefix:prefix, reserved:false, children:[], splitTo:null, comment:"" }); } return arr; } let root=null; function loadPrefixDropdown(){ let select=document.getElementById("basePrefix"); for(let p=8;p<=30;p++){ let option=document.createElement("option"); option.value=p; option.text="/"+p+" ("+prefixToMask(p)+")"; if(p==24) option.selected=true; select.appendChild(option); } } function initNetwork(){ let ipInput=document.getElementById("baseIp").value.trim(); let prefix=parseInt(document.getElementById("basePrefix").value); document.getElementById("warning").innerHTML=""; if(!isValidIp(ipInput)){ document.getElementById("warning").innerHTML="Invalid IP address"; return; } let network=getNetworkAddress(ipInput,prefix); if(network!==ipInput){ document.getElementById("warning").innerHTML= "Adjusted to network address: "+network; } root={ network:network, prefix:prefix, parentPrefix:null, reserved:false, children:[], splitTo:null, comment:"" }; redraw(); } function renderSummary(){ let info=subnetInfo(root.network,root.prefix); document.getElementById("networkSummary").innerHTML= ` <b>Network:</b> ${info.network}<br> <b>Mask:</b> ${info.mask}<br> <b>Range:</b> ${info.first} - ${info.last}<br> <b>Broadcast:</b> ${info.broadcast}<br> <b>Hosts:</b> ${info.hosts} `; } function copy(text){ navigator.clipboard.writeText(text); } function findNode(node,network,prefix){ if(node.network===network && node.prefix===prefix) return node; for(let c of node.children){ let f=findNode(c,network,prefix); if(f) return f; } return null; } function updateComment(network,prefix,value){ let node=findNode(root,network,prefix); if(node) node.comment=value; } function handleAction(select,network,prefix){ let value=select.value; if(!value) return; let node=findNode(root,network,prefix); if(value==="reset"){ node.reserved=false; node.children=[]; node.splitTo=null; } else if(value==="reserve"){ node.reserved=true; node.children=[]; node.splitTo=null; } else if(value.startsWith("split")){ let newPrefix=parseInt(value.split("-")[1]); node.reserved=false; node.splitTo=newPrefix; node.children=splitSubnet(network,prefix,newPrefix); } redraw(); } function render(node,level,rows){ let info=subnetInfo(node.network,node.prefix); let dropdown=`<select onchange="handleAction(this,'${node.network}',${node.prefix})">`; dropdown+=`<option value="">Action</option>`; if(node.reserved || node.splitTo) dropdown+=`<option value="reset">Reset</option>`; dropdown+=`<option value="reserve" ${node.reserved?"selected":""}>Reserve</option>`; for(let p=node.prefix+1;p<=30;p++){ let selected=(node.splitTo===p)?"selected":""; dropdown+=`<option value="split-${p}" ${selected}> Split /${p} - ${usableHosts(p)} Hosts </option>`; } dropdown+=`</select>`; rows.push(` <tr class="${node.reserved?'reserved':''}"> <td style="padding-left:${level*30}px"> ${info.network} <button class="copybtn" onclick="copy('${info.network}')">Copy</button> <br> <div class="binary"> ${networkBinaryWithHighlight(node.network,node.prefix,node.parentPrefix)} </div> </td> <td> ${info.mask} <button class="copybtn" onclick="copy('${info.mask}')">Copy</button> </td> <td> ${info.first} <button class="copybtn" onclick="copy('${info.first}')">Copy</button> </td> <td> ${info.last} <button class="copybtn" onclick="copy('${info.last}')">Copy</button> </td> <td>${info.broadcast}</td> <td>${info.hosts}</td> <td> ${node.reserved?'':`<input value="${node.comment}" oninput="updateComment('${node.network}',${node.prefix},this.value)">`} </td> <td>${dropdown}</td> </tr> `); node.children.forEach(c=>render(c,level+1,rows)); } function redraw(){ renderSummary(); let rows=[]; rows.push(` <table> <thead> <tr> <th>Network</th> <th>Mask</th> <th>First IP</th> <th>Last IP</th> <th>Broadcast</th> <th>Hosts</th> <th>Comment</th> <th>Action</th> </tr> </thead> <tbody> `); render(root,0,rows); rows.push("</tbody></table>"); document.getElementById("output").innerHTML=rows.join(""); } function resetNetwork(){ document.getElementById("output").innerHTML=""; } function toggleDark(){ document.body.classList.toggle("dark"); } loadPrefixDropdown(); initNetwork(); </script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.7 |
proxy
|
phpinfo
|
Settings