Skip to content
Snippets Groups Projects
Commit ad65dd0a authored by Phil's avatar Phil
Browse files

Added RandRegExp()

parent 94444ec5
No related branches found
No related tags found
No related merge requests found
...@@ -64,14 +64,15 @@ class VolatileValue: ...@@ -64,14 +64,15 @@ class VolatileValue:
class RandField(VolatileValue): class RandField(VolatileValue):
pass pass
class RandNum(RandField): class RandNum(RandField):
min = 0 min = 0
max = 0 max = 0
def __init__(self, min, max): def __init__(self, min, max):
self.seq = randseq(min,max) self.min = min
self.max = max
def _fix(self): def _fix(self):
return self.seq.next() # XXX: replace with sth that guarantee unicity
return random.randrange(self.min, self.max+1)
class RandNumGamma(RandField): class RandNumGamma(RandField):
def __init__(self, alpha, beta): def __init__(self, alpha, beta):
...@@ -88,34 +89,41 @@ class RandNumGauss(RandField): ...@@ -88,34 +89,41 @@ class RandNumGauss(RandField):
return int(round(random.gauss(self.mu, self.sigma))) return int(round(random.gauss(self.mu, self.sigma)))
class RandNumExpo(RandField): class RandNumExpo(RandField):
def __init__(self, lambd): def __init__(self, lambd, base=0):
self.lambd = lambd self.lambd = lambd
self.base = base
def _fix(self): def _fix(self):
return int(round(random.expovariate(self.lambd))) return self.base+int(round(random.expovariate(self.lambd)))
class RandByte(RandNum): class RandSeq(RandNum):
def __init__(self, min, max):
self.seq = randseq(min,max)
def _fix(self):
return self.seq.next()
class RandByte(RandSeq):
def __init__(self): def __init__(self):
RandNum.__init__(self, 0, 2L**8-1) RandSeq.__init__(self, 0, 2L**8-1)
class RandShort(RandNum): class RandShort(RandSeq):
def __init__(self): def __init__(self):
RandNum.__init__(self, 0, 2L**16-1) RandSeq.__init__(self, 0, 2L**16-1)
class RandInt(RandNum): class RandInt(RandSeq):
def __init__(self): def __init__(self):
RandNum.__init__(self, 0, 2L**32-1) RandSeq.__init__(self, 0, 2L**32-1)
class RandSInt(RandNum): class RandSInt(RandSeq):
def __init__(self): def __init__(self):
RandNum.__init__(self, -2L**31, 2L**31-1) RandSeq.__init__(self, -2L**31, 2L**31-1)
class RandLong(RandNum): class RandLong(RandSeq):
def __init__(self): def __init__(self):
RandNum.__init__(self, 0, 2L**64-1) RandSeq.__init__(self, 0, 2L**64-1)
class RandSLong(RandNum): class RandSLong(RandSeq):
def __init__(self): def __init__(self):
RandNum.__init__(self, -2L**63, 2L**63-1) RandSeq.__init__(self, -2L**63, 2L**63-1)
class RandChoice(RandField): class RandChoice(RandField):
def __init__(self, *args): def __init__(self, *args):
...@@ -165,7 +173,7 @@ class RandMAC(RandString): ...@@ -165,7 +173,7 @@ class RandMAC(RandString):
v = RandByte() v = RandByte()
elif "-" in template[i]: elif "-" in template[i]:
x,y = template[i].split("-") x,y = template[i].split("-")
v = RandNum(int(x,16), int(y,16)) v = RandSeq(int(x,16), int(y,16))
else: else:
v = int(template[i],16) v = int(template[i],16)
self.mac += (v,) self.mac += (v,)
...@@ -205,7 +213,165 @@ class RandOID(RandString): ...@@ -205,7 +213,165 @@ class RandOID(RandString):
oid.append(i) oid.append(i)
return ".".join(oid) return ".".join(oid)
from pprint import pprint
class RandRegExp(RandField):
def __init__(self, regexp, lambda_=0.3,):
self._regexp = regexp
self._lambda = lambda_
@staticmethod
def choice_expand(s): #XXX does not support special sets like (ex ':alnum:')
m = ""
invert = s and s[0] == "^"
while True:
p = s.find("-")
if p < 0:
break
if p == 0 or p == len(s)-1:
m = "-"
if p:
s = s[:-1]
else:
s = s[1:]
else:
c1 = s[p-1]
c2 = s[p+1]
rng = "".join(map(chr, range(ord(c1),ord(c2)+1)))
s = s[:p-1]+rng+s[p+1:]
res = m+s
if invert:
res = "".join([chr(x) for x in xrange(256) if chr(x) not in res])
return res
@staticmethod
def stack_fix(lst, index):
r = ""
mul = 1
for e in lst:
if type(e) is list:
if mul != 1:
mul = mul-1
r += RandRegExp.stack_fix(e[1:]*mul, index)
# only the last iteration should be kept for back reference
f = RandRegExp.stack_fix(e[1:], index)
for i,idx in enumerate(index):
if e is idx:
index[i] = f
r += f
mul = 1
elif type(e) is tuple:
kind,val = e
if kind == "cite":
r += index[val-1]
elif kind == "repeat":
mul = val
elif kind == "choice":
if mul == 1:
c = random.choice(val)
r += RandRegExp.stack_fix(c[1:], index)
else:
r += RandRegExp.stack_fix([e]*mul, index)
mul = 1
else:
if mul != 1:
r += RandRegExp.stack_fix([e]*mul, index)
mul = 1
else:
r += str(e)
return r
def _fix(self):
stack = [None]
index = []
current = stack
i = 0
ln = len(self._regexp)
interp = True
while i < ln:
c = self._regexp[i]
i+=1
if c == '(':
current = [current]
current[0].append(current)
elif c == '|':
p = current[0]
ch = p[-1]
if type(ch) is not tuple:
ch = ("choice",[current])
p[-1] = ch
else:
ch[1].append(current)
current = [p]
elif c == ')':
ch = current[0][-1]
if type(ch) is tuple:
ch[1].append(current)
index.append(current)
current = current[0]
elif c == '[' or c == '{':
current = [current]
current[0].append(current)
interp = False
elif c == ']':
current = current[0]
choice = RandRegExp.choice_expand("".join(current.pop()[1:]))
current.append(RandChoice(*list(choice)))
interp = True
elif c == '}':
current = current[0]
num = "".join(current.pop()[1:])
e = current.pop()
if "," not in num:
n = int(num)
current.append([current]+[e]*n)
else:
num_min,num_max = num.split(",")
if not num_min:
num_min = "0"
if num_max:
n = RandNum(int(num_min),int(num_max))
else:
n = RandNumExpo(self._lambda,base=int(num_min))
current.append(("repeat",n))
current.append(e)
interp = True
elif c == '\\':
c = self._regexp[i]
if c == "s":
c = RandChoice(" ","\t")
elif c in "0123456789":
c = ("cite",ord(c)-0x30)
current.append(c)
i += 1
elif not interp:
current.append(c)
elif c == '+':
e = current.pop()
current.append([current]+[e]*(int(random.expovariate(self._lambda))+1))
elif c == '*':
e = current.pop()
current.append([current]+[e]*int(random.expovariate(self._lambda)))
elif c == '?':
if random.randint(0,1):
current.pop()
elif c == '.':
current.append(RandChoice(*[chr(x) for x in xrange(256)]))
elif c == '$' or c == '^':
pass
else:
current.append(c)
return RandRegExp.stack_fix(stack[1:], index)
def __repr__(self):
return "<%s [%r]>" % (self.__class__.__name__, self._regexp)
# Automatic timestamp # Automatic timestamp
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment