Skip to content

Instantly share code, notes, and snippets.

@radu-c
Last active April 27, 2020 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radu-c/df0408cb55de758e03b7568cc05f1865 to your computer and use it in GitHub Desktop.
Save radu-c/df0408cb55de758e03b7568cc05f1865 to your computer and use it in GitHub Desktop.
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 '\\d+'
}
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
@radu-c
Copy link
Author

radu-c commented Apr 27, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment