-
-
Save ollyg/b5d0824a2876c995c67812e643505b90 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const zip = (arr, ...arrs) => { | |
return arr.map((val, i) => arrs.reduce((a, arr) => [...a, arr[i]], [val])) | |
} | |
const cidrToRegex = cidr => { | |
const [ip, prefix] = cidr.split('/') | |
const base = ip | |
.split('.') | |
.map(val => parseInt(val)) | |
.reduce((base, val) => (base << 8) | val, 0) | |
const shift = 32 - parseInt(prefix) | |
const start = (base >> shift) << shift | |
const end = start | ((1 << shift) - 1) | |
const regex = (lower, upper) => { | |
if (lower === upper) { | |
return `${lower}` | |
} | |
let exp = parseInt(Math.log10(upper - lower)) | |
const lowerS = `${lower}` | |
const upperS = `${upper}` | |
if (lowerS.substr(-1,1) > upperS.substr(-1,1) && exp == 0) { | |
// increasing exp due to base 10 wrap to next exp" | |
exp += 1 | |
} | |
const delta = 10 ** exp | |
if (lower === 0 && upper === 255) { | |
return '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])' | |
} | |
if (delta === 1) { | |
let val = '' | |
const z = zip(lowerS.split(''), upperS.split('')) | |
for (const [a, b] of z) { | |
if (a === b) { | |
val += a | |
} else if ((a === '0' && b === '9') || (b === '0' && a === '9')) { | |
val += '\\d' | |
} else if (Math.abs(b - a) === 1) { | |
val += `[${a}${b}]` | |
} else { | |
if (b < a) { | |
val += `[${b}-${a}]` | |
} else { | |
val += `[${a}-${b}]` | |
} | |
} | |
} | |
return val | |
} | |
const floor_ = x => parseInt(Math.floor(x / delta) * delta) | |
const genClasses = () => { | |
const parts = [] | |
const first = floor_(upper) - delta | |
const last = floor_(lower) | |
const p = Array(exp).fill('\\d').join('') | |
let xs = first | |
while (xs > last) { | |
const x = `${xs}` | |
parts.push(`${x.substr(exp - 1, 1)}${p}`) | |
xs -= delta | |
} | |
parts.push(regex(lower, floor_(lower) + (delta - 1))) | |
parts.push(regex(floor_(upper), upper)) | |
return parts | |
} | |
return '(?:' + genClasses().join('|') + ')' | |
} | |
const getParts = () => { | |
const parts = [] | |
for (let x = 24; x >= 0; x -= 8) { | |
parts.push(regex((start >> x) & 255, (end >> x) & 255)) | |
} | |
return parts | |
} | |
return `(?:${getParts().join('\\.')})` | |
} | |
module.exports.cidrToRegex = cidrToRegex |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This updated version of the original fixes three bugs found.