I was trying to work out the total time of this pcap directory I was working on but didnt want to see a huge number of seconds, so I have written something to change it into a human readable form. It is largely the same as a version I found on the internet but I cant remember where. Apologies.
<><><>
def human_time(secs):
mins, secs = divmod(secs, 60)
hours, mins = divmod(mins, 60)
days, hours = divmod(hours, 24)
weeks, days = divmod(days, 7)
return '%02d weeks %02d days %02d hours %02d mins %02d secs' % (weeks, days,hours, mins, secs)
<><><>
Friday, 26 November 2010
Monday, 22 November 2010
Calculating running Averages in Python
It took a while, but I got it to work. Again there was a nod in the direction of the internet (mostly here), the source of all my knowledge. I'll just throw up the code as it ought to be fairly self explanatory, but then I always say that.
<><><>
def make_av():
def std_dev(value):
from math import sqrt
std_dev.tot += 1 # Calculate necessary values
std_dev.sum += value
std_dev.sq_sum += (value * value)
if std_dev.tot < 2: # Cant have sd with less than 2 packets
return 0.0
# Return a tuple of the running mean followed by the running standard deviation
return (std_dev.sum / std_dev.tot, sqrt(abs((std_dev.tot * std_dev.sq_sum - std_dev.sum**2) / (std_dev.tot *(std_dev.tot-1)))))
std_dev.tot, std_dev.sum, std_dev.sq_sum = [0.0]*3 # Reset variables
return (std_dev)
<><><>
So you create an instance of make_av() and input the value you wish to get the averages of. The function returns a tuple of the mean and standard deviation. Done
<><><>
def make_av():
def std_dev(value):
from math import sqrt
std_dev.tot += 1 # Calculate necessary values
std_dev.sum += value
std_dev.sq_sum += (value * value)
if std_dev.tot < 2: # Cant have sd with less than 2 packets
return 0.0
# Return a tuple of the running mean followed by the running standard deviation
return (std_dev.sum / std_dev.tot, sqrt(abs((std_dev.tot * std_dev.sq_sum - std_dev.sum**2) / (std_dev.tot *(std_dev.tot-1)))))
std_dev.tot, std_dev.sum, std_dev.sq_sum = [0.0]*3 # Reset variables
return (std_dev)
<><><>
So you create an instance of make_av() and input the value you wish to get the averages of. The function returns a tuple of the mean and standard deviation. Done
Friday, 12 November 2010
Listing a directory Numerically in Python
Damn you sort function! I spent a good two days trying to establish how to list a mixed alphanumeric name into NUMERIC rather than ALPHABETICAL order. The best I was getting (with filenames like "pcap-date-1") was them listed in order 1,11,2,3,33. Which makes no sense at all. Surprisingly this appears to be non-trivial. It was also thrown off by the fact that the first pcap doesnt have a number, just an empty placeholder to signify 0.
I tried multiple approaches to this and there didn't seem to be a clear solution out there so I ended up writing my own, heavily based on various source from my good friend the internet of course.
<><><>
def list_numeric(delimiter, path):
import os
temp_list=[]
final_list=[]
for i in os.listdir(path):
y=i.split(delimiter)
if y[-1:] == ['']:
y.pop()
y.append('0')
temp_list.append((i,y[-1:]))
for i in range(len(temp_list)):
final_list.append(i)
for i,j in temp_list:
final_list[int(j[0])] = i
return final_list
<><><>
It works by splitting the file name by the delimiter ("-" in this case) and taking the final section of the split as the numeric sort term. The "if y[-1:]" section is there so that the missing 0 is added for the file which is at the very start but not numerically marked. This is then added into a list of tuples, associating each file with it's numeric sort term in each element of a temporary list.
Now based on the length of this list another empty list is created. As a result we have an element free for each of the files to be slotted into, in order, based on their numeric sort value. Once all the files have been slotted into their correct positions in "final_list", the list is returned. Et voila!
I tried multiple approaches to this and there didn't seem to be a clear solution out there so I ended up writing my own, heavily based on various source from my good friend the internet of course.
<><><>
def list_numeric(delimiter, path):
import os
temp_list=[]
final_list=[]
for i in os.listdir(path):
y=i.split(delimiter)
if y[-1:] == ['']:
y.pop()
y.append('0')
temp_list.append((i,y[-1:]))
for i in range(len(temp_list)):
final_list.append(i)
for i,j in temp_list:
final_list[int(j[0])] = i
return final_list
<><><>
It works by splitting the file name by the delimiter ("-" in this case) and taking the final section of the split as the numeric sort term. The "if y[-1:]" section is there so that the missing 0 is added for the file which is at the very start but not numerically marked. This is then added into a list of tuples, associating each file with it's numeric sort term in each element of a temporary list.
Now based on the length of this list another empty list is created. As a result we have an element free for each of the files to be slotted into, in order, based on their numeric sort value. Once all the files have been slotted into their correct positions in "final_list", the list is returned. Et voila!
Friday, 5 November 2010
Local Variable Creation on the Fly
Before I started on this adventure in Python I had designed a script in Bash to see if it worked and establish the structure of the program. I might throw that stuff up at some stage as well as there may well be some nifty solutions to problems in there. In particular I was very pleased at how I was able to generate variables on the fly based on how many entries in a list I had, for example.
Having moved to Python this was more of a challenge, but I managed to throw something together using the "vars()" local variable ability.
<><><>
if ap_members.count((packet.info, packet.addr2)) == 0: # If not found before add and setup storage
ap_members.append((packet.info, packet.addr2))
vars()[packet.info + "_" + packet.addr2 + "_working"] = deque(maxlen=2)
vars()[packet.info + "_" + packet.addr2 + "_list"] = 0
vars()[packet.info + "_" + packet.addr2 + "_average"] = make_av() # Stats
vars()[packet.info + "_" + packet.addr2 + "_power"] = make_av()
vars()[packet.info + "_" + packet.addr2 + "_list"] += 1 # Tracks num of beacons per AP
<><><>
This is just a little code example of the principle which is implemented continually through the program I am working on. Here I have a stream of packets coming in and I want to create a series of variables every time a new link is found, i.e. every time a client and an Access Point talk to each other. If the "packet.info" (SSID) and "packet.addr2" (destination address) has not been seen before then it is added to the list of known associations and has a deque, a list and two stats instances created.
Using this approach any time a new variable needs created I jut append with a different "_x" term and define it as I see fit. Now any time the "packet.info" and "packet.addr2" fields are fulfilled the information is added for that combination and that combination alone.
I have since been told that my solution would have been better utilising a dictionary and a series of lists but I disagree. Once you realise what this code is doing it is very very easy to start adapting it and adding new variables. The description of what each variable does is clear as day and you can guarantee it is going to be created irrespective of how many times it is called. Yes it clutters the screen somewhat, but I think it's a fair trade off.
Subscribe to:
Comments (Atom)