{
  "schemaVersion": 1,
  "slug": "ip-subnet-calculator",
  "category": "productivity",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "f840376007cfc1bbfc33c9a35168e4463606383e7916946efef99e299f2b9955",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/ip-subnet-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "usable = 2^(32−p)−2 normally; /31 point-to-point = 2; /32 host route = 1",
    "vars": [
      [
        "N",
        "Usable host addresses"
      ],
      [
        "p",
        "Prefix length / CIDR (0–32)"
      ],
      [
        "IP",
        "IPv4 address"
      ],
      [
        "mask",
        "Subnet mask"
      ],
      [
        "network",
        "Network address"
      ],
      [
        "broadcast",
        "Broadcast address"
      ]
    ],
    "note": "Conventional prefixes reserve network/broadcast; /31 point-to-point has 2 usable endpoints and /32 is one host route."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const values=[ip1,ip2,ip3,ip4,prefix]; if(values.some(n=>!Number.isInteger(n))||[ip1,ip2,ip3,ip4].some(n=>n<0||n>255)||prefix<0||prefix>32)return{netmask:null,networkAddress:null,broadcastAddress:null,firstHost:null,lastHost:null,totalAddresses:null,usableHosts:null,wildcard:null,__error:'inputError'}; const octets=[ip1,ip2,ip3,ip4]; const ipInt=((octets[0]<<24)>>>0)+(octets[1]<<16)+(octets[2]<<8)+octets[3]; const p=prefix; const maskInt=p===0?0:(0xFFFFFFFF<<(32-p))>>>0; const networkInt=(ipInt&maskInt)>>>0; const broadcastInt=(networkInt|(~maskInt>>>0))>>>0; const toStr=n=>[(n>>>24)&255,(n>>>16)&255,(n>>>8)&255,n&255].join('.'); const totalAddresses=Math.pow(2,32-p); const usableHosts=p===31?2:p===32?1:totalAddresses>2?totalAddresses-2:0; return {netmask:toStr(maskInt),networkAddress:toStr(networkInt),broadcastAddress:toStr(broadcastInt),firstHost:usableHosts>0?toStr(p>=31?networkInt:networkInt+1):'—',lastHost:usableHosts>0?toStr(p===31?broadcastInt:p===32?networkInt:broadcastInt-1):'—',totalAddresses,usableHosts,wildcard:toStr((~maskInt)>>>0)};",
    "inputs": [
      {
        "name": "ip1",
        "type": "number",
        "default": 192,
        "min": 0,
        "max": 255,
        "step": 1,
        "slider": true
      },
      {
        "name": "ip2",
        "type": "number",
        "default": 168,
        "min": 0,
        "max": 255,
        "step": 1,
        "slider": true
      },
      {
        "name": "ip3",
        "type": "number",
        "default": 1,
        "min": 0,
        "max": 255,
        "step": 1,
        "slider": true
      },
      {
        "name": "ip4",
        "type": "number",
        "default": 10,
        "min": 0,
        "max": 255,
        "step": 1,
        "slider": true
      },
      {
        "name": "prefix",
        "type": "number",
        "default": 24,
        "min": 0,
        "max": 32,
        "step": 1,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "netmask",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "networkAddress",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "broadcastAddress",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "firstHost",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "lastHost",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "totalAddresses",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "usableHosts",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "wildcard",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
