Skip to content

Instantly share code, notes, and snippets.

@mordyovits
Forked from 2xyo/cidr2regex.py
Last active March 18, 2016 15:34
Show Gist options
  • Save mordyovits/ab2ba4635a1ed9d2065b to your computer and use it in GitHub Desktop.
Save mordyovits/ab2ba4635a1ed9d2065b to your computer and use it in GitHub Desktop.
#!/usr/bin/python
''' Not my script, found on the Internet, and rediscovered on my hard drive
'''
import sys
def cidr_to_regex(cidr):
ip, prefix = cidr.split('/')
base = 0
for val in map(int, ip.split('.')):
base = (base << 8) | val
shift = 32 - int(prefix)
start = base >> shift << shift
end = start | (1 << shift) - 1
def regex(lower, upper):
if lower == upper:
return str(lower)
from math import log10
exp = int(log10(upper - lower))
if (int(str(lower)[-1]) > int(str(upper)[-1])):
# increasing exp due to base 10 wrap to next exp"
exp += 1
delta = 10 ** exp
if lower == 0 and upper == 255:
return "\d+"
if delta == 1:
val = ""
for a, b in zip(str(lower), str(upper)):
if a == b:
val += str(a)
elif (a, b) == ("0", "9"):
val += '\d'
elif int(b) - int(a) == 1:
val += '[%s%s]' % (a, b)
else:
val += '[%s-%s]' % (a, b)
return val
def gen_classes():
floor_ = lambda x: int(round(x / delta, 0) * delta)
xs = range(floor_(upper) - delta, floor_(lower), -delta)
for x in map(str, xs):
yield '%s%s' % (x[:-exp], r'\d' * exp)
yield regex(lower, floor_(lower) + (delta - 1))
yield regex(floor_(upper), upper)
return "(?:{})".format('|'.join(gen_classes()))
def get_parts():
for x in range(24, -1, -8):
yield regex(start >> x & 255, end >> x & 255)
return '^%s$' % r'\.'.join(get_parts())
for line in sys.stdin.readlines():
print cidr_to_regex( line )
print
@mordyovits
Copy link
Author

This is still not fully correct. 1.2.148.0/22 outputs ^1.2.1[45][8901].\d+$ which matches things it shouldn't

1.2.141.27 <-- incorrectly matches this
1.2.148.27
1.2.149.27
1.2.150.27
1.2.151.27
1.2.153.27

@mordyovits
Copy link
Author

It should output ^1.2.(14[89]|15[01]).\d+$ but that would require some bigger changes.

@mordyovits
Copy link
Author

Ok, I think this is correct now. I can't find a failure case.

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