Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Python for Networking and Security

You're reading from   Mastering Python for Networking and Security Leverage the scripts and libraries of Python version 3.7 and beyond to overcome networking and security issues

Arrow left icon
Product type Paperback
Published in Jan 2021
Publisher Packt
ISBN-13 9781839217166
Length 538 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
José Manuel Ortega José Manuel Ortega
Author Profile Icon José Manuel Ortega
José Manuel Ortega
Arrow right icon
View More author details
Toc

Table of Contents (22) Chapters Close

Preface 1. Section 1: The Python Environment and System Programming Tools
2. Chapter 1: Working with Python Scripting FREE CHAPTER 3. Chapter 2: System Programming Packages 4. Section 2: Network Scripting and Extracting Information from the Tor Network with Python
5. Chapter 3: Socket Programming 6. Chapter 4: HTTP Programming 7. Chapter 5: Connecting to the Tor Network and Discovering Hidden Services 8. Section 3: Server Scripting and Port Scanning with Python
9. Chapter 6: Gathering Information from Servers 10. Chapter 7: Interacting with FTP, SFTP, and SSH Servers 11. Chapter 8: Working with Nmap Scanner 12. Section 4: Server Vulnerabilities and Security in Python Modules
13. Chapter 9: Interacting with Vulnerability Scanners 14. Chapter 10: Identifying Server Vulnerabilities in Web Applications 15. Chapter 11: Security and Vulnerabilities in Python Modules 16. Section 5: Python Forensics
17. Chapter 12: Python Tools for Forensics Analysis 18. Chapter 13: Extracting Geolocation and Metadata from Documents, Images, and Browsers 19. Chapter 14: Cryptography and Steganography 20. Assessments 21. Other Books You May Enjoy

Exploring Python data structures

In this section, we will review different types of data structures, including lists, tuples, and dictionaries. We will see methods and operations for managing these data structures and practical examples where we review the main use cases.

Lists

Lists in Python are equivalent to structures as dynamic vectors in programming languages such as C. We can express literals by enclosing their elements between a pair of brackets and separating them with commas. The first element of a list has index 0.

Consider the following example: a programmer can create a list using the append() method by adding objects, printing the objects, and then sorting them before printing again. We describe a list of protocols in the following example, and use the key methods of a Python list as add, index, and remove:

>>> protocolList = []
>>> protocolList.append(“ftp”)
>>> protocolList.append(“ssh”)
>>> protocolList.append(“smtp”)
>>> protocolList.append(“http”)
>>> print(protocolList)
[‘ftp’,’ssh’,’smtp’,’http’]
>>> protocolList.sort()
>>> print(protocolList)
[‘ftp’,’http’,’smtp’,’ssh’]
>>> type(protocolList)
<type ‘list’>
>>> len(protocolList)
4

To access specific positions, we can use the index() method, and to delete an element, we can use the remove() method:

>>> position = protocolList.index(“ssh”)
>>> print(“ssh position”+str(position))
ssh position 3
>>> protocolList.remove(“ssh”)
>>> print(protocolList)
[‘ftp’,’http’,’smtp’]
>>> count = len(protocolList)
>>> print(“Protocol elements “+str(count))
Protocol elements 3

To print out the whole protocol list, use the following instructions. This will loop through all the elements and print them:

>>> for protocol in protocolList:
>>> 	print (protocol)
ftp
http
smtp

Lists also have methods that help manipulate the values within them and allow us to store more than one variable within them and provide a better way to sort object arrays in Python. These are the techniques commonly used to control lists:

  • .append(value): Appends an element at the end of the list
  • .count(‘x’): Gets the number of ‘x’ in the list
  • .index(‘x’): Returns the index of ‘x’ in the list
  • .insert(‘y’,’x’): Inserts ‘x’ at location ‘y’
  • .pop(): Returns the last element and also removes it from the list
  • .remove(‘x’): Removes the first ‘x’ from the list
  • .reverse(): Reverses the elements in the list
  • .sort(): Sorts the list in ascending order

The indexing operator allows access to an element and is expressed syntactically by adding its index in brackets to the list, list [index]. You can change the value of a chosen element in the list using the index between brackets:

protocols[4] = ‘ssh’
print(“New list content: “, protocols)

Also, you can copy the value of a specific position to another position in the list:

protocols[1] = protocols[4]
print(“New list content:”, protocols)

The value inside the brackets that selects one element of the list is called an index, while the operation of selecting an element from the list is known as indexing.

Adding elements to a list

We can add elements to a list by means of the following methods:

  • list.append(value): This method allows an element to be inserted at the end of the list. It takes its argument’s value and puts it at the end of the list that owns the method. The list’s length then increases by one.
  • list.insert(location, value): The insert() method is a bit smarter since it can add a new element at any place in the list, and not just at the end. It takes as arguments first the required location of the element to be inserted and then the element to be inserted.

Reversing a list

Another interesting operation that we perform in lists is the one that offers the possibility of getting elements in a reverse way in the list through the reverse() method:

>>> protocolList.reverse()
>>> print(protocolList)
[‘smtp’,’http’,’ftp’]

Another way to do the same operation is to use the -1 index. This quick and easy technique shows how you can access all the elements of a list in reverse order:

>>> protocolList[::-1]
>>> print(protocolList)
[‘smtp’,’http’,’ftp’]

Searching elements in a list

In this example, we can see the code for finding the location of a given element inside a list. We use the range function to get elements inside protocolList and we compare each element with the element to find. When both elements are equal, we break the loop and return the element.

You can find the following code in the search_element_list.py file:

protocolList = [“FTP”, “HTTP”, “SNMP”, “SSH”]
toFind = “SSH”
found = False
for i in range(len(protocolList)):
        found = protocolList[i] == toFind
        if found:
                break
if found:
        print(“Element found at index”, i)
else:
        print(“Element not found”)

Now that you know how to add, reverse, and search for elements in a list, let’s move on to learning about tuples in Python.

Tuples

A tuple is like a list, except its size cannot change and cannot add more elements than originally specified. The parentheses delimit a tuple. If we try to modify a tuple element, we get an error that indicates that the tuple object does not support element assignment:

>>>tuple=(“ftp”,”ssh”,”http”,”snmp”)
>>>tuple[0]
‘ftp’
>>>tuple[0]=”FTP”
Traceback (most recent call last):
    File “<stdin>”, line 1, in <module>
TypeError: ‘tuple’ object does not support item assignment

Now that you know the basic data structures for working with Python, let’s move on to learning about Python dictionaries in order to organize information in the key-value format.

Python dictionaries

The Python dictionary data structure is probably the most important in the entire language and allows us to associate values with keys. A key is any immutable object. The value associated with a key can be accessed with the indexing operator. In Python, dictionaries are implemented using hash tables.

A Python dictionary is a way of storing information in the format of key: value pairs. Python dictionaries have curly brackets, {}. Let’s look at a protocols dictionary, with names and numbers, for example:

>>> services = {“ftp”:21, “ssh”:22, “smtp”:25, “http”:80}

The limitation with dictionaries is that we cannot use the same key to create multiple values. This will overwrite the duplicate key preceding value.

Using the update method, we can combine two distinct dictionaries into one. In addition, the update method will merge existing elements if they conflict:

>>> services = {“ftp”:21, “ssh”:22, “smtp”:25, “http”:80}
>>> services2 = {“ftp”:21, “ssh”:22, “snmp”:161, “ldap”:389}
>>> services.update(services2)
>>> print(services)
{“ftp”:21, “ssh”:22, “smtp”:25, “http”:80,”snmp”:161, “ldap”:389}

The first value is the key, and the second the key value. We can use any unchangeable value as a key. We can use numbers, sequences, Booleans, or tuples, but not lists or dictionaries, since they are mutable.

The main difference between dictionaries and lists or tuples is that values contained in a dictionary are accessed by their name and not by their index. You may also use this operator to reassign values, as in the lists and tuples:

>>> services[“http”]= 8080

This means that a dictionary is a set of key-value pairs with the following conditions:

  • Each key must be unique: That means it is not possible to have more than one key of the same value.
  • A key may be data of any type: It may be a number or a string.
  • A dictionary is not a list: A list contains a set of numbered values, while a dictionary holds pairs of values.
  • The len() function: This works for dictionaries and returns the number of key-value elements in the dictionary.

    Important note

    In Python 3.7, dictionaries have become ordered collections by default.

When building a dictionary, each key is separated from its value by a colon, and we separate items by commas. The .keys() method will return a list of all keys of a dictionary and the .items() method will return a complete list of elements in the dictionary. The following are examples involving these methods:

  • services.keys() is a method that will return all the keys in the dictionary.
  • services.items() is a method that will return the entire list of items in a dictionary:
>>> keys = services.keys()
>>> print(keys)
[‘ftp’, ‘smtp’, ‘ssh’, ‘http’, ‘snmp’]

Another way is based on using a dictionary’s method called items(). The method returns a list of tuples (this is the first example where tuples are something more than just an example of themselves) where each tuple is a key-value pair:

  1. Enter the following command:
    >>> items = services.items()
    >>> print(items)
    [(‘ftp’, 21), (‘smtp’,25), (‘ssh’, 22), (‘http’, 80), (‘snmp’, 161)]

    From the performance point of view, when it is stored, the key inside a dictionary is converted to a hash value to save space and boost efficiency when searching or indexing the dictionary. The dictionary may also be printed, and the keys browsed in a particular order.

  2. The following code sorts the dictionary elements in ascending order by key using the sort() method:
    >>> items.sort()
    >>> print(items)
    [(‘ftp’, 21), (‘http’, 80), (‘smtp’, 25), (‘snmp’, 161), (‘ssh’, 22)]
  3. Finally, you might want to iterate over a dictionary and extract and display all the key-value pairs with a classical for loop:
    >>> for key,value in services.items():
    >>>	print(key,value)
    ftp 21
    smtp 25
    ssh 22
    http 80
    snmp 16

Assigning a new value to an existing key is simple due to dictionaries being fully mutable. There are no obstacles to modify them:

  1. In this example, we’re going to replace the value of the http key:
    >>> services[‘http’] = 8080
    >>> print(services)
    {“ftp”:21, “ssh”:22, “smtp”:25, “http”:8080,”snmp”:161}
  2. Adding a new key-value pair to a dictionary is as easy as modifying a value. Only a new, previously non-existent key needs to be assigned to one:
    >>> services[‘ldap’] = 389
    >>> print(services)
    {“ftp”:21, “ssh”:22, “smtp”:25, “http”:8080,”snmp”:161, “ldap”:389}

Note that this is very different behavior compared to lists, which don’t allow you to assign values to non-existing indices.

Now that you know the main data structures for working with Python, let’s move on to learning how to structure our Python code with functions and classes.

You have been reading a chapter from
Mastering Python for Networking and Security - Second Edition
Published in: Jan 2021
Publisher: Packt
ISBN-13: 9781839217166
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image