(ip: string, mask: number)
| 50 | (((parts[0] << 24) | |
| 51 | (parts[1] << 16) | |
| 52 | (parts[2] << 8) | |
| 53 | parts[3]) >>> 0); |
| 54 | |
| 55 | const maskNum = mask === 0 ? 0 : ((~0 << (32 - mask)) >>> 0); |
| 56 | const netNum = ipNum & maskNum; |
| 57 | |
| 58 | const netParts = [ |
| 59 | (netNum >>> 24) & 255, |
| 60 | (netNum >>> 16) & 255, |
| 61 | (netNum >>> 8) & 255, |
| 62 | netNum & 255, |
| 63 | ]; |
| 64 | |
| 65 | return `${netParts.join(".")}/${mask}`; |
| 66 | } |
| 67 | |
| 68 | function normalizeIP(input: string): string | null { |
| 69 | const clean = input.trim(); |
| 70 | if (!clean || clean.includes("/")) return null; |
| 71 | const m = clean.match(/^(\d{1,3}(?:\.\d{1,3}){3})$/); |
| 72 | if (!m) return null; |
| 73 | const ip = m[1]; |
| 74 | if (!isValidIPv4(ip)) return null; |
| 75 | return ip; |
| 76 | } |
no test coverage detected