Showing posts with label Learning. Show all posts
Showing posts with label Learning. Show all posts

Wednesday, May 23, 2018

The Basics of Prolog Programming Language

Prolog is a logic programming language that is based on facts and rules. The idea is to create a set of facts related to specific domain. After that, we create rules that can be used to answer questions (or queries). For example, we may create a facts that can be used to identify a human if he is a man or a woman. In top of that, we can add more facts to state that this human is a father or a mother of another human. Once we have the given facts, we can create rules. For example, we can define a rule that can be used to find  the father of another human.


In this post, we will learn the basics of Prolog language in the simplest way. For this purpose, we will be using an online editor that can be used to write Prolog code and test it. The tool is called SWISH and can be fount at http://swish.swi-prolog.org/.

When we open the link, we will see that the page has 3 parts, one for creating new file, one for the output and one for asking questions.

The Layout of The Tool
To start writing Prolog code, simply click 'Program' and the code editor will appear.


Prolog Facts

In order to create Prolog rules, first we have to provide some facts. Suppose that we have 5 humans, one has the name 'john', another one has the name 'sara', another one has the name 'ali' and one has the name 'paul' and the last one with the name 'hannah'. The first facts that we are going to write is to state that a human can be a man or a woman. We can till from the names that 'john' is a man and 'sara' is a woman. Writing such facts in Prolog can be done as follows:

man(john).
man(ali).
man(paul).
woman(sara).
woman(hannah).


In Prolog, a fact is written as follows

fact_name(fact_attrs...).

Every fact we write in Prolog must end with a 'dot', and each fact can have one or more parameters (or attributes). Now that we know how to write facts, let's add more facts to our program. Let's say that 'john' is a father of 'ali', 'paul' and 'hannah'. Also let's say that 'sara' is the mother of 'ali', 'paul' and 'hannah'.

man(john).
man(ali).
man(paul).
woman(sara).
woman(hannah).
father(john,ali).
father(john,paul).
father(john,hannah).
mother(sara,ali).
mother(sara,paul).
mother(sara,hannah).


Once we have the given facts, we can ask questions about them and get answers. For example, we can ask the question 'Is john a man?'. Another question we could ask is 'Who is the mother of ali?'. A question in Prolog is called "query". In the next section, we will learn how to ask questions in Prolog.

Prolog Queries

One of the simplest queries in Prolog are the queries that are applied to the facts. The result of such queries will be either "true" or "false" if all the attributes of the query are known. For example, the result of running a query in one of the first 5 facts with one of the 5 names will be either "true" or "false".

In the example that we will see, we want to know if a person is a man or not. Prolog query has the following basic form: "?- rule_or_fact(vars...)". It is possible to construct more complex queries but we will do it later. For now, let's focus at the basics. The "?-" part is provided by the editor by default. All what we have to do is to write the other part.

In SWISH, we write the query in the place where it says " Your query goes here ...". After writing the query, All what we have to do is to click "run" and the result will appear. Let's give it a try.



As we can see, "ali" is a man since we got "true". Now we want to try something else. Suppose that we would like to get All women. To do that, we have to learn about new concept in Prolog which is variables.

Prolog Variables

A variable in Prolog can be used to answer queries. Variables are passed as an arguments to rules and facts to get specific values. Any parameter that starts with a capital letter is considered as a variable. For example, if we say 'woman(Sara)', 'Sara' is now a variable not an attribute. The  final value of the variable is based on the provided facts and rules. Now, to get all women, we pass a variable to the fact 'woman()'. Prolog will set the value of that variable to the name of the woman.

 As we can see, we have got our first woman. To get the rest, all what we have to do is to click "Next" till the execution is finished.

Now let's try something new. Suppose that we would like to know who is the father of 'ali'. To ask such as query, we write it as 'father(X, ali)'. In this case, 'X' will be equal to the father of 'ali'.


Suppose that we have a person that has unknown father. What will be the value of 'X' in this case? Let's try it. To do that, we will add new man called 'ibrahim' and try to find his father.

Simply we got 'false'. Whenever we try to apply a rule that does not exist, we will get 'false'. Also if we try the rule with a name that does not exist, we will get false. For example, if we try 'father(X, dania)', this will also give false.

Monday, October 2, 2017

Building a Responsive Grid System Using CSS: Part 1

Starting today, I will be posting a series of posts in which I will be teaching how to build a responsive grid system from scratch using CSS. Every week, I will try to add one post. This is the first post and we will be reviewing some basic concepts related to CSS.

Introduction

In these days, many people are browsing the web using many other devices other than personal computers and laptops. For that reason, one factor to consider while developing a website is to make it adaptive to different screen sizes. One way would be to create variants of the website for each device which is not good idea. The best option is to go with creating a responsive grid system for the website. Once you have the grid ready, you can use it to build the UI of the web site.

Before we continue with the process of building the grid system, you must have the basic knowledge of the following topics:

  • HTML Basics.
  • CSS Basics.
  • Using Web Browser Inspector (optional but very helpful).

Review: Box Model

Before we start building the grid system, let’s review some basic concepts that we need. The one and most important concept is the “Box Model”. The idea of box model is that HTML elements are represented as a rectangle. The rectangle has 5 important properties. The 5 properties are used to specify the Real width and height of HTML element. The 5 properties are:

  • Width
  • Height
  • Border
  • Margin
  • Padding

The width and height properties are used to specify the width and height of the content area within the HTML element. The border is simply a visible line that is used to show the shape of HTML element. The margin is used to specify how far the given HTML element from the other elements. The padding is used to specify how far the content area of HTML element from the border.

The border, the margin and padding are represented as boxes that surround the content area as illustrated by the next image.

By default, web browsers use only the content area width and height to compute the total width and height of HTML element. Basically this means that width property of HTML element = content width. This means that if we add a border of size 2px and a padding of size 5px to an element with width property = 100px, the total visible width will be 114px. We can see that in the next example.

HTML Code

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <style type="text/css">
            .div1{
                border: 2px black solid;
                background-color: #2d8659;
                width: 200px
            }
            .childDiv1{
                border: 2px black solid;
                background-color: #99e6e6;
                width: 100px;
                padding: 5px
            }
            .childDiv2{
                border: 2px black solid;
                background-color: #EEEEFF;
                width: 100px;
                padding: 5px
            }
        </style>
    </head>
    <body>
        <div class="div1">
            <div class="childDiv1">
                Child Div1
            </div>
            <div class="childDiv1">
                Child Div2
            </div>
        </div>
    </body>
</html>

What we have in here is one DIV element with two DIV elements inside it. What we care about is the width of the inner two DIV elements. The “width” property is set to 100px. The border property is set to 2px and the padding is set to 5px. When we use the inspector of a web browser, we can see that the total element width is 114px.

This behavior can be overridden by specifying the value of the CSS property “box-sizing”. This property is used to tell the web browser how to calculate the width and height of HTML element. The default value for this property is “content-box” which means that the value of “width” property will be the width of content area. Another possible value for this property is “border-box”. If the value of the “box-sizing” property is set to “border-box”, the value of the property width will be content width + border + padding. For example, if we set the width property to be 100px with a border of size 2px and a padding of 5px, the total element width will be 100px. 10 of the 100 will be for the padding and 4 will be for the border and 86px for the content.

Let’s modify the code above and change the value of the property “box-sizing” and set it to “border box” and observe the effect.

HTML Code

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <style type="text/css">
            
            /*This selector is used to 
             *selects all HTML elements
             */

            *{
                box-sizing: border-box;
            }
            .div1{
                border: 2px black solid;
                background-color: #2d8659;
                width: 200px
            }
            .childDiv1{
                border: 2px black solid;
                background-color: #99e6e6;
                width: 100px;
                padding: 5px
            }
            .childDiv2{
                border: 2px black solid;
                background-color: #EEEEFF;
                width: 100px;
                padding: 5px
            }
        </style>
    </head>
    <body>
        <div class="div1">
            <div class="childDiv1">
                Child Div1
            </div>
            <div class="childDiv1">
                Child Div2
            </div>
        </div>
    </body>
</html>

As we can see, the width of the element is the same as we set even when we have border and padding. This will be useful as we build our grid system later. For that reason, we will set the “box-sizing” for all elements to “border-box” including pseudo -elements. To do that, we use the following CSS ruleset:

CSS Code

1 2 3 4 5

*, *::before,*::after{
    box-sizing:border-box;
}

Just a reminder, pseudo-elements uses double semi-colon and pseudo-classes uses single semi-colon. Next, we will start by understanding the idea behind the grid system.

One thing to note is that we did not talk about the margin. One thing to mention about the margin is that it will be added up to the element total width regardless of the property "box-sizing".

In the next post, we will be learning about the basic idea behind grids and we will be interdicting a new concept which is the CSS At-Rule.

Thursday, June 15, 2017

Java Basics: Variable Naming Rules and Conventions

One of the important things to learn regarding java programming language is what is allowed and not allowed in choosing the name of a variable. Basically there are rules for choosing the name of a variable and there are conventions. In this post, we will be learning about the rules that govern variable naming in java language in addition to the conversions that is used by any java developer. We will include code examples to illustrate naming rules.

Naming Rules

1 - Variable name can start only with a letter, underscore (_) or dollar sign ($).

//This is allowed
int firstNum;

//This is allowed
int FirstNum;

//This is allowed
int _firstNum;


//This is allowed
int $firstNum;


//This is not allowed
int !firstNum;



2 - Variable name can contain numbers after the first letter.

//This is allowed
int burger1;


//This is not allowed
int 1burger;

//This is allowed
int burger2;


3 - Variable name cannot contain spaces or special characters.

//This is not allowed
int burger 1;

//This is not allowed
int burger-2;

//This is not allowed
int burger(3);


4 - Uppercase name differ from lower case.

//This one variable
int burger;


//This one is another one
int BURGER;

//Also this one is not same as above
int BURGer;


5 - Java keywords cannot be used for variable name (e.g. void).

//not allowed
int void;



6 - The length of the variable can be of any length.

Naming Conventions

Naming conventions are used by the developers to understand the meaning of a variable. For example, if you wrote a code and someone else reads that code, he will be able to understand your code easier if you use naming conventions. I my self follow the given conversions when I write Java code.

The following naming conventions are good to follow when you start writing your code:

  • Do not use dollar sign or underscore in the name of your variables.
  • Use meaningful names.
  • Use uppercase letters for the constant variables(e.g. PI = 3.14).
  • If the constant has two words, use underscore to separate words (e.g. MAX_SIZE = 4).


Wednesday, April 19, 2017

Overview of Program Memory Structure

One of the most important concepts that a computer scientist must know about is how the program looks like when its executing. The first thing that happens when we double click a program icon in Windows OS is that it is loaded into memory. The program is not loaded randomly for sure. Each program has a small part of the memory. That small part is partitioned into smaller parts.

The next picture shows a basic overview of how program memory is  divided.

Usual Memory Structure of a Program.


 This structure is used by almost any program that is loaded into memory. Now, let's start by explaining the meaning of each part of the given diagram. In many cases, the higher address are put at the bottom. For instance, the address 0xffffffff will be at the bottom of the diagram (Reverse the diagram).

The Stack

The stack is a place where the program stack is located. From its name, we can infer that it is a "Stack Data structure". A program stack is manly consist of method calls. When a method is called, the return address is "pushed" to the stack. Once the execution of the method is completed, the address is "poped" from the top of the stack. Usually the term "Call Stack" is used to describe this type of stack.

The Heap

For sure you have heard of this term before. The memory heap is something difference from the heap data structure. The memory heap is a place that is used for dynamically located memory. It is used for the data that is given at the run time. For example, the size of input string from the user is unknown. In this case, it will be placed at the heap. The heap will only contain program data. In C programming language, the system call "malloc" is used to locate heap space and the system call "free" is used to free the space. The next code example shows how it is done in C language.


#include <stdio.h>
#include <stdlib.h>

int main() {
    int numOfBytes = 100;
    //a buffer that will contain user input
    char * input;
    //locate space for user input
    input = malloc(numOfBytes);
    //read string from the user
    fgets(input,numOfBytes,stdin);
    printf("You give me '%s'",input);
    //must free memory after use
    free(input);
    return 0;
}

Uninitialized Data

Also known as BSS Segment. This segment of memory contains the global variables and static data that has not been initialized. For example, the variable "static int myInt; " will be located at uninitialized data segment.

Initialized Data 

This part of memory will contain the global and static variables which have been initialized within the code. This means that the variable can be accessed from any where in the program.

Code 

This part of memory contains the actual instructions of the program. Usually, this part of memory is placed in the top of the stack or bellow the heap in order to prevent overflows from override the data inside it.


This is the most basic view of program memory. For sure there are many thins inside each section of the memory but we only want to look at the abstract view.

Monday, April 17, 2017

JavaScript: Working With Cookies


This is a simple lesson that has all what you need to know about web cookies using JavaScript. In this lesson, we will learn the following:
  • What is a Cookie.
  • How to Create them.
  • Setting Expiry Date of a Cookie.
  • View a Cookie using JavaScript.
  • Deleting a Cookie.

What is a Cookie?

The correct question to ask is 'What is a Web Cookie?'.
A web cookie is a small piece of text that is created by a web site's
and sent to the user's computer and stored temporarily. The main functionality
of the web cookie is to provide a state for the stateless web pages.

A web cookie has 3 main components:

  • Name.
  • Value.
  • Zero or more pairs of key/value.
Here is an example of a web cookie:


my_name = ibrahim

This is the most simplest cookie that can be created. It has the name 'my_name'
and a value of 'ibrahim'.

It is very simple to create cookies with JavaScript. The following syntax can
be used to create the previous cookie:


document.cookie = "my_name = ibrahim";


When a cookie is created, it is better to specify an expiry date for it.
If we do not specify an expiry date, the cookie will be deleted once the
browser window is closed. Expiry date is considered as key/value pair


document.cookie = "my_name = ibrahim; expires = Sat, 04 Feb 2017 19:43:41 UTC";

It is good practice to set the time to UTC (Coordinated Universal Time) since the visitors of a web site may have different time.

To make a cookie expire after specific time, we can use 'Date' object to to that.


//create new date object

var date = new Date();

//we want our cookie to expire after 5 days

var days = 5

var currentTime = date.getTime()

/*


note that 1 second = 1000 milliseconds

and 1 minute has 60 seconds and

one hour has 60 minutes and one day has 24 hours.

5 days = 1000*60*60*24*5 = 432000000 milliseconds

If we want from our cookie to expire after 2 hours, we set

the time to (current time + 1000*60*120)


*/

date.setTime(currentTime + 1000*60*60*24*days);

document.cookie = "my_name = ibrahim; expires = "+date.toUTCString();

In order to update the content of the cookie, we use the same syntax that is used
to create a cookie.


//this is our new cookie

document.cookie = "my_name = ibrahim; expires=Sat, 04 Feb 2017 19:43:41 GMT";



//this is the same cookie with new value

document.cookie = "my_name = ali; expires=Sat, 04 Feb 2017 19:43:41 GMT";


To view all cookies for the web site, we simply use the following:


allCookies = document.cookie;

console.log(allCookies);

What we get is actually a string of text that shows all the available cookies that
is sent by the web site. To get specific cookie value, we have to build a function
that can split cookies.

To delete a cookie, we have only to update the expiry date of the cookie to a date that'd
has been passed. But before we delete a cookie, we have to set the 'path' value of the cookie.
some browsers does not allow the deletion of a cookie with no path.



//create cookie

document.cookie = "my_name = ibrahim; expires = Sat, 04 Feb 2030 19:43:41 UTC;path=/";

//delete cookie

document.cookie = "my_name = ibrahim; expires = Sat, 04 Feb 2010 00:00:00 UTC;path=/";


Source: Programming Academia

Wednesday, March 29, 2017

Python: Using PyCrypto Library, Part 1

Last week, the instructor of ICS 444 has gave us new assignment. In the assignment, it is required to use one of Python cryptographic libraries. As for me, I have decided to use a library called PyCrypto. In this blog post, I will be discussing the following topics regarding the selected library:
  1. Installing the library in Windows 7 OS.
  2. Computing SHA512 digest of a message.
  3. Using MD5 + AES to Hash and Encrypt a Message.
Note that I have never used Python programming language before. I will explain only the parts that I will be using from the language.

Installing The Library in Windows

Installing PyCrypto library in windows is very simple. All what we have to do is to execute the following command in cmd.exe:

pip install --use-wheel --no-index --find-links=https://github.com/sfbahr/PyCrypto-Wheels/raw/master/pycrypto-2.6.1-cp35-none-win_amd64.whl pycrypto

After executing the command, the library will be installed.


After Executing this command, the library will be installed. Note that the given command is for python 64 bit windows. If your python installation is 32 bits, change pycrypto-2.6.1-cp35-none-win_amd64.whl to pycrypto-2.6.1-cp35-none-win32.whl.


Applying PyCrypto Algorithms

Suppose that we have a text file named "PythonCrypto.txt" and the file contains the following Text:
Cryptography is the practice and study of techniques for secure communication in the presence of third parties called adversaries.   These adversaries are often referred to as Eve in cryptography, while the sender and recipient of messages are called Alice and Bob respectively. More generally, cryptography is about constructing and analyzing protocols that prevent third parties or the public from reading private messages.

The algorithms of PyCrypto Library will be applied to the content of the given file. The first thing we will do is to read the contend of the file as follows:

file = open("PythonCrypto.txt", 'r')
message = file.read();
#print file content to check if it was opened
print(message)

This code snippet can be used to only read the content of a file. The method open() in the given example has two parameters, the first is the name of the file and the second is the mode in which we will open the file. 'r' stands for 'read' and 'w' stands for 'write'. After opening the file, we read its content and store it in the variable 'message' using the method 'read()'. The text that comes after the '#' is a comment in python language. A comment is a piece of text that does not affect the output of a program. It is only used to describe what your code is doing. the 'print()' is a function that is used to show the output in the console. It is defined in the heart of python language.

Computing SHA512 Hash 

Now that we have the content of the file, let's try to apply some algorithms to it. The first thing we will do is to compute SHA512 digest of the text. To do that, we have to tell Python that we are going to use a function from PyCrypto library. The statement that is used to do that is as follows:

from Crypto.Hash import SHA512

This statement is called import statement. It must be the first statement in our python file. Now, let's compute the digest. The code for that is as follows:

from Crypto.Hash import SHA512
file = open("PythonCrypto.txt", 'r')
message = file.read();
print(message)
digest = SHA512.new(message).hexdigest();
print(digest);

If we run the code as it is shown above, we will get the following error message:

TypeError: Unicode-objects must be encoded before hashing

This error basically means that we have to specify the type of text encoding that we are using for the given text. To specify the encoding of the text, we call the method 'encode()' as follows:

from Crypto.Hash import SHA512
file = open("PythonCrypto.txt", 'r')
message = file.read();
print(message)
digest = SHA512.new(message.encode('utf-8')).hexdigest();
print(digest);

This will solve the problem and will show the SHA512 digest of the message. It will be something like this:

6881eae82c054693543a9111f612b7252a19003483f75cd86455d3b72cfb6bbe32882d275f8ce26346f5b48d345d459796a0067031186f9a3196ac9b6964b2a3

This is a hexadecimal representation of the digest. Now, instead of printing the digest, let's store it in a file called "SHA512Digest.txt". The code for performing such as task is as follows:

from Crypto.Hash import SHA512
file = open("PythonCrypto.txt", 'r')
message = file.read();
print(message)
digest = SHA512.new(message.encode('utf-8')).hexdigest();
print(digest);
file = open("SHA512Digest.txt", 'w')
file.write(digest)
file.close()

The given code will create a new file called "SHA512Digest.txt". After that, the method 'write()' will write the digest to the file. The method 'close()' will close the file after writing the digest to it.

Using MD5 Hash With AES Cipher

Now that we have the basics of using PyCrypto, we will start using it in little bit advanced way. The first thing that we will do is to compute the MD5 digest of the message. After that, we will be using AES Cipher to encrypt the text. Finally, we will send the message to another program using text file.

Hashing + Encryption, What Can we Get?

By using the digest of the message, we can guaranty the integrity of the message that is been sent. If the message has been modified while being sent, the digest will be different at the receiver side. By using AES, we guaranty confidentiality. Basically no one can read the content of the message except the one who has the key to decrypt the message.

Basics of AES:

AES Cipher has two parameters, the first one is the data that will be encrypted and the second one is the key. The cipher accepts data of size 16 bytes only. This means in order to encrypt larger data set, we have to divide the data set into smaller parts of size 16 bytes and use AES in each part. The key size for the cipher has 3 different sizes, 16 bytes, 24 bytes or 32 bytes.

AES in PyCrypto Library

Before using AES, we have to import it as we did with SHA algorithm. But in this case, AES will be in a different place. AES can be found in 'Crypto.Cipher.AES'. According to the documentation of AES, the algorithm takes 3 parameters, A key, Mode and Initialization Vector (IV). The initialization vector will be used depending on the mode. If the mode is 'AES.MODE_ECB' or 'AES.MODE_CTR', the initialization vector is not needed. In our case, we will ignore the initialization vector and use 'AES.MODE_ECB'. The following code example shows how to encrypt and decrypt a simple text of size 16 bytes using AES in PyCrypt.

from Crypto.Cipher import AES
cipher = AES.new("1111111111111111", AES.MODE_ECB, b'')
#each letter is one byte 
message = '0123456789abcdef' 
print('Original message = '+message)
encryptedMessage = cipher.encrypt('aaaaaaaaaaaaaaaa')
print('Encrypted Message = '+encryptedMessage)
decryptedMessage = cipher.decrypt(encryptedMessage)
print('Decrypted Message = '+decryptedMessage)


The "b''" implies that we are supplying a byte string to the algorithm as initialization vector. This will be ignored since the mode is 'AES.MODE_ECB'. If we run the code as it is, it will not run and we will get the following error:

TypeError: Can't convert 'bytes' object to str implicitly

This error means that the type of data that returned by AES algorithm is byte and it cannot be shown in the console as it is. What we have to do is to change it to string. After doing that, the code will work fine.

from Crypto.Cipher import AES
cipher = AES.new("1111111111111111", AES.MODE_ECB, b'')
message = '0123456789abcdef' 
print('Original message = '+message)
encryptedMessage = cipher.encrypt('aaaaaaaaaaaaaaaa')
print('Encrypted Message = '+str(encryptedMessage))
decryptedMessage = cipher.decrypt(encryptedMessage)
print('Decrypted Message = '+str(decryptedMessage))

The output of the given code will be something like this:

Original message = 0123456789abcdef
Encrypted Message = b'\xc6\xb9\xd1\x02\xdd\xea\xb1i\xf3$\xcb\xdb\xe73\xf0\n'
Decrypted Message = b'aaaaaaaaaaaaaaaa'

We can notice that the decrypted message has the letter 'b' which we don't want to appear with the text. For this reason, we will be using different way to display the decrypted message. We will use 'bytes.decode()'.

from Crypto.Cipher import AES

cipher = AES.new("1111111111111111", AES.MODE_ECB, b'')
message = '0123456789abcdef'
print('Original message = '+message)
encryptedMessage = cipher.encrypt('aaaaaaaaaaaaaaaa')
print('Encrypted Message = '+str(encryptedMessage))
decryptedMessage = cipher.decrypt(encryptedMessage)
print('Decrypted Message = '+bytes.decode(decryptedMessage,'utf-8'))

Using MD5 + AES to Hash and Encrypt a File

Now that we know how to use hash functions and ciphers from PyCrypto library, we will be using them in a simple application. First, we will be computing MD5 hash of the file "PythonCrypto.txt". Then we will be storing the hash in a file. After that, we will use AES to encrypt the file and store the key in one file and the encrypted data in another file. Lastly, another program will open the 3 generated files to verify the integrity of the data. The code for the first program is as follows:

from Crypto.Hash import MD5
from Crypto.Cipher import AES


key = "1111111111111111" 
cipher = AES.new(key, AES.MODE_ECB, b'')
file = open('PythonCrypto.txt', 'r')
# notice the 'wb'. the 'b' in here means we are writing binary data to file
encryptedFile = open("AESEncrypted.txt", 'wb')
while True:
    data = file.read(16)
    if data:
        encryptedMessage = cipher.encrypt(data)
        encryptedFile.write(encryptedMessage)
    else:
        encryptedFile.close()
        break
file = open("AESKey.txt", 'w')
file.write(key)
file.close()
 
# notice the 'rb' here. This means we are reading binary data 
encryptedFile = open("AESEncrypted.txt", 'rb')
message = encryptedFile.read()
digest = MD5.new(message.encode('utf-8')).hexdigest()
file = open("MD5Digest.txt", 'w')
file.write(digest)
file.close() 

When we run the code, it will not run and the following error will appear:
ValueError: Input strings must be a multiple of 16 in length
We are sure that the length of the 'data' variable is multiple of 16 bytes since we are providing the number 16 in the 'read()' function. When we print the data that we read from the file, we will see something as follows:
Cryptography
The first 3 characters are not part of the text on the file. The 3 characters called byte order mark (BOM). they are basically used to tell the encoding type of the file. To solve the problem, we have to skip the 3 characters. So, before we go into the loop, we will read 3 bytes and then enter the loop. The code now will become as follows:

from Crypto.Hash import MD5
from Crypto.Cipher import AES


key = "1111111111111111" 
cipher = AES.new(key, AES.MODE_ECB, b'')
file = open('PythonCrypto.txt', 'r')
encryptedFile = open("AESEncrypted.txt", 'wb')
file.read(3)
while True:
    data = file.read(16)
    if data:
        encryptedMessage = cipher.encrypt(data)
        encryptedFile.write(encryptedMessage)
    else:
        encryptedFile.close()
        break 
file = open("AESKey.txt", 'w')
file.write(key)
file.close()
encryptedFile = open("AESEncrypted.txt", 'rb')
message = encryptedFile.read()
digest = MD5.new(message.encode('utf-8')).hexdigest()
file = open("MD5Digest.txt", 'w')
file.write(digest)
file.close() 


When we run the code again, we still get the same error. The reason for that is because the content of the file is not a multiple of 16 bytes. To solve the problem, we have to add a check when we reach the end of the file to add some bytes to make it multiple of 16. We will add white spaces at the end of the data. After doing so, the code should work 100% fine.

from Crypto.Hash import MD5
from Crypto.Cipher import AES


key = "1111111111111111" 
cipher = AES.new(key, AES.MODE_ECB, b'')
file = open('PythonCrypto.txt', 'r')
encryptedFile = open("AESEncrypted.txt", 'wb')
file.read(3)
while True:
    data = file.read(16)
    if data:
        if len(data) != 16:
            while len(data) != 16:
                data += ' '
        encryptedMessage = cipher.encrypt(data)
        encryptedFile.write(encryptedMessage)
    else:
        encryptedFile.close()
        break 
file = open("AESKey.txt", 'w')
file.write(key)
file.close()
encryptedFile = open("AESEncrypted.txt", 'rb')
message = encryptedFile.read()
digest = MD5.new(message).hexdigest()
file = open("MD5Digest.txt", 'w')
file.write(digest)
file.close()


The code looks little bit messy. What we will do is to modify it and use methods (or functions) instead to make it cleaner. We will create 3 methods, one to encrypt the file, one to compute the digest and one for running the two methods. The syntax for defining a method in python is as follows:

def method_name(zero_or_more_params):
    # methode code goes here

As we can see, it is very simple. Note that to run the code, your methods should come before the place where you are using them. After fixing the code, it will become as follows:
from Crypto.Hash import MD5
from Crypto.Cipher import AES


def aes_encrypt(key, key_file_name, file_name, encrypted_file_name):
    cipher = AES.new(key, AES.MODE_ECB, b'')
    file = open(file_name, 'r')
    encrypted_file = open(encrypted_file_name, 'wb')
    file.read(3)
    while True:
        data = file.read(16)
        if data:
            if len(data) != 16:
                while len(data) != 16:
                    data += ' '
            encrypted_message = cipher.encrypt(data)
            encrypted_file.write(encrypted_message)
        else:
            encrypted_file.close()
            break     
    file = open(key_file_name, 'w')
    file.write(key)
    file.close()


def compute_md5_digest(digest_file_name, file_to_digest):
    encrypted_file = open(file_to_digest, 'rb')
    message = encrypted_file.read()
    digest = MD5.new(message).hexdigest()
    md5_file = open(digest_file_name, 'w')
    md5_file.write(digest)
    md5_file.close()


def main():
    key = '1111111111111111'    
    data_file_name = 'PythonCrypto.txt'    
    encrypted_file_name = 'AESEncrypted.txt'    
    key_file_name = 'AESKey.txt'    
    digest_file_name = 'MD5Digest.txt'    
    aes_encrypt(key, key_file_name, data_file_name, encrypted_file_name)
    compute_md5_digest(digest_file_name, encrypted_file_name)

main()

Now we will start working with the other program which will verify the integrty of the message + decrypt it.The program will be very short. The first thing the program will do is to open the encrypted file, compute the digest and compare it with the digest that was created by the first program. If the two are the same, then the message was not modified by any one and it is safe to decrypt it. We will create this program as a method. The code for that is as follows:

def program_2():
    print('Running Program #2')
    encrypted_file_name = 'AESEncrypted.txt'     
    key_file_name = 'AESKey.txt' 
    program_1_digest_file = 'MD5Digest.txt' 
    decrypted_file_name = 'AESDecrypt.txt'     
    file = open(program_1_digest_file)
    program_1_digest = file.read()
    file = open(encrypted_file_name,'rb')
    message = file.read()
    digest = MD5.new(message).hexdigest()
    if digest == program_1_digest:
        print('Data Integrity Verified!')
        print('Decrypting data')
        key_file = open(key_file_name)
        key = key_file.read()
        print('Key = '+key)
        encrypted_file = open(encrypted_file_name,'rb')
        decrypted_file = open(decrypted_file_name,'w')
        cipher = AES.new(key, AES.MODE_ECB, b'')
        while True:
            data = encrypted_file.read(16)
            if data:
                decrypted_message = cipher.decrypt(data)
                decrypted_file.write(bytes.decode(decrypted_message, 'utf-8'))
            else:
                print('Decrypting Finished!')
                print('Decrypted Data can be found inside '+encrypted_file_name)
                decrypted_file.close()
                break 
    else:
        print('Data was modified by someone!!')

Now we can merge the given code with the previous code to get our full two programs:

from Crypto.Hash import MD5
from Crypto.Cipher import AES


def aes_encrypt(key, key_file_name, file_name, encrypted_file_name):
    print('Encrypting '+file_name+' using AES')
    print('Key = '+key)
    print('File to encrypt = '+file_name)
    print('Encrypted file name = '+encrypted_file_name)
    print('Note: the encrypted data is stored as binary')
    cipher = AES.new(key, AES.MODE_ECB, b'')
    file = open(file_name, 'r')
    encrypted_file = open(encrypted_file_name, 'wb')
    file.read(3)
    while True:
        data = file.read(16)
        if data:
            if len(data) != 16:
                while len(data) != 16:
                    data += ' '
            encrypted_message = cipher.encrypt(data)
            encrypted_file.write(encrypted_message)
        else:
            encrypted_file.close()
            break     
    file = open(key_file_name, 'w')
    file.write(key)
    file.close()
    print('File Encryption Completed!')


def compute_md5_digest(digest_file_name, file_to_digest):
    print('Computing MD5 digest')
    print('Input file = '+file_to_digest)
    print('Output file = '+digest_file_name)
    encrypted_file = open(file_to_digest, 'rb')
    message = encrypted_file.read()
    digest = MD5.new(message).hexdigest()
    md5_file = open(digest_file_name, 'w')
    md5_file.write(digest)
    md5_file.close()
    print('MD5 digest finished!')


def program_1():
    print('Running Program #1')
    key = '1111111111111111'    data_file_name = 'PythonCrypto.txt' 
    encrypted_file_name = 'AESEncrypted.txt' 
    key_file_name = 'AESKey.txt' 
    digest_file_name = 'MD5Digest.txt'     
    aes_encrypt(key, key_file_name, data_file_name, encrypted_file_name)
    compute_md5_digest(digest_file_name, encrypted_file_name)
    print('Program #1 Finished!')


def program_2():
    print('Running Program #2')
    encrypted_file_name = 'AESEncrypted.txt' 
    key_file_name = 'AESKey.txt' 
    program_1_digest_file = 'MD5Digest.txt' 
    decrypted_file_name = 'AESDecrypt.txt'     
    file = open(program_1_digest_file)
    program_1_digest = file.read()
    file = open(encrypted_file_name, 'rb')
    message = file.read()
    digest = MD5.new(message).hexdigest()
    if digest == program_1_digest:
        print('Data Integrity Verified!')
        print('Decrypting data')
        key_file = open(key_file_name)
        key = key_file.read()
        print('Key = '+key)
        encrypted_file = open(encrypted_file_name, 'rb')
        decrypted_file = open(decrypted_file_name, 'w')
        cipher = AES.new(key, AES.MODE_ECB, b'')
        while True:
            data = encrypted_file.read(16)
            if data:
                decrypted_message = cipher.decrypt(data)
                decrypted_file.write(bytes.decode(decrypted_message, 'utf-8'))
            else:
                print('Decrypting Finished!')
                print('Decrypted Data can be found inside '+encrypted_file_name)
                decrypted_file.close()
                break 
    else:
        print('Data was modified by someone!!')
    print('Program #2 Finished!')


# inside main, we can select which program to run. 
# program_1() means the one who will send the data. 
# program_2 means the one who will receive the data.
def main():
    program_1()
    program_2()


main()

The next step will be to learn  about asymmetric keys in PyCrypt and how to use them  to encrypt and decrypt the file. Basically we will be using digital signature.


Common Errors and how to Fix Them:

Error Message: 
ImportError: No module named 'winrandom'

Fix:
Edit the file 'Python35\lib\site-packages\Crypto\Random\OSRNG\nt.py'. Change '

import winrandom' to '
from . import winrandom'.

Error Message: 
ImportError: DLL load failed: The specified module could not be found.
Fix:
This message appear when trying to import something from the library. The reason for that is the installation is broken. You have to re-install PyCrypto library.

Error Message: 
ValueError: Input strings must be a multiple of 16 in length.
This error can appear if an algorithm needs specific data length. For example, the input to AES must be 16 bytes in length. if it is more or less, this error will appear.
Fix: Check data length that it is 16 bytes.

Error Message:
TypeError: Can't convert 'bytes' object to str implicitly
This error appears when we try to print other data types such as byte. The print method accepts only string type.
Fix:
Use str(data_to_print).

Error Message:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
This error can happen when reading from file. The error means that the encoding of the file is not 'utf-8'. All what you have to do is open the file and save it in 'utf-8' encoding.

Error Message:
TypeError: write() argument must be str, not bytes
This error can happen when we try to write data into a file. The method 'write()' will only accept data of type string if we use 'w'. This means we have to use the method 'str(data)' to convert our data into string before using 'write()' method. Another solution is to use 'wb' if we are writing raw data to the file.


In part 2, we will learn how to use digital signature to sign our data. Part 2 will be posted in the future.