File manager - Edit - /home/kridsana/webapp.cm.in.th/663012801/u66301280015/สอบ IP/VLSM.html
Back
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>VLSM Hierarchical Calculator</title> <style> body{ font-family:Arial; background:#f4f6f9; padding:20px; } .header{ background:#222; color:white; padding:15px; margin-bottom:20px; } input, select{ padding:6px; margin:5px; } table{ border-collapse:collapse; width:100%; margin-top:20px; } th,td{ border:1px solid #ccc; padding:6px; } th{ background:#333; color:white; } tr:hover{ background:#ffeeba !important; } .reserved{ background:#ff3b3b; color:white; font-weight:bold; } .status-split{ color:#0066cc; font-weight:bold; } </style> </head> <body> <div class="header"> <h2>VLSM Hierarchical Calculator</h2> <div class="info"> โดย นายนรบดินทร์ นุชทรวง <br> รหัสประจำตัว: 68543206080-2 </div> </div> <label>Network Address:</label> <input type="text" id="baseIp" value="192.168.80.0"> <label>Subnet Mark:</label> <select id="basePrefix"></select> <button onclick="initNetwork()">Start</button> <div id="output"></div> <script> // ================= IP UTILS ================= 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 ipToBinary(ip){ return ip.split('.') .map(octet => parseInt(octet) .toString(2) .padStart(8,'0')) .join('.'); } function usableHosts(prefix){ return (2**(32-prefix))-2; } function subnetInfo(network,prefix){ let base=ipToInt(network); let size=2**(32-prefix); return{ network:network+"/"+prefix, binary:ipToBinary(network), mask:prefixToMask(prefix), first:intToIp(base+1), last:intToIp(base+size-2), broadcast:intToIp(base+size-1), hosts:size-2 } } // ================= SPLIT ================= 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, reserved:false, children:[], splitTo:null, comment:"" }); } return arr; } let root=null; // ================= INIT ================= 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(){ root={ network:document.getElementById("baseIp").value, prefix:parseInt(document.getElementById("basePrefix").value), reserved:false, children:[], splitTo:null, comment:"" }; redraw(); } // ================= SEARCH ================= 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; } // ================= COMMENT ================= function updateComment(network,prefix,value){ let node=findNode(root,network,prefix); node.comment=value; } // ================= ACTION ================= function handleAction(select,network,prefix){ let value=select.value; if(!value) return; let node=findNode(root,network,prefix); if(value==="reserve"){ node.reserved=true; node.children=[]; node.splitTo=null; node.comment=""; } else if(value.startsWith("split")){ let newPrefix=parseInt(value.split("-")[1]); node.reserved=false; node.splitTo=newPrefix; node.children=splitSubnet(network,prefix,newPrefix); } redraw(); } // ================= RENDER ================= function render(node,level,rows){ let info=subnetInfo(node.network,node.prefix); let currentValue=""; if(node.reserved){ currentValue="reserve"; } else if(node.splitTo){ currentValue="split-"+node.splitTo; } let dropdown=`<select onchange="handleAction(this,'${node.network}',${node.prefix})">`; if(!currentValue){ dropdown+=`<option value="" selected>Action</option>`; } else if(node.reserved){ dropdown+=`<option value="reserve" selected>Reserved</option>`; } else if(node.splitTo){ dropdown+=`<option value="split-${node.splitTo}" selected> Split → /${node.splitTo} (${prefixToMask(node.splitTo)}) </option>`; } dropdown+=`<option value="reserve">Reserve</option>`; for(let p=node.prefix+1;p<=30;p++){ dropdown+=` <option value="split-${p}"> Split /${p} (${prefixToMask(p)}) - ${usableHosts(p)} Hosts </option>`; } dropdown+=`</select>`; rows.push(` <tr class="${node.reserved?'reserved':''}"> <td style="padding-left:${level*30}px"> ${info.network}<br> <span class="binary">${info.binary}</span> </td> <td>${info.mask}</td> <td>${info.first}</td> <td>${info.last}</td> <td>${info.broadcast}</td> <td>${info.hosts}</td> <td> ${ node.reserved ? '' : `<input class="comment-box" value="${node.comment}" placeholder="" oninput="updateComment('${node.network}',${node.prefix},this.value)">` } </td> <td>${!node.reserved?dropdown:''}</td> </tr> `); node.children.forEach(c=>render(c,level+1,rows)); } function redraw(){ let rows=[]; rows.push(` <table> <tr> <th>Network</th> <th>Subnet Mask</th> <th>First IP</th> <th>Last IP</th> <th>Broadcast</th> <th>Usable Hosts</th> <th>Comment</th> <th>Action</th> </tr> `); render(root,0,rows); rows.push("</table>"); document.getElementById("output").innerHTML=rows.join(""); } loadPrefixDropdown(); initNetwork(); </script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.45 |
proxy
|
phpinfo
|
Settings