python programming project ii encryption/decryptionstudents.cypresscollege.edu/cis247/lc11.pdf ·...

27
Python Programming Penniel P. Wu, PhD. 334 Lecture #11 Python Programming Project II Encryption/Decryption The Proposed Algorithm The algorithm contains two segments: encryption and decryption. The encryption algorithm is performed by a given quadratic equation. The decryption algorithm is the opposite of encryption, which is performed by the “inverse” of the quadratic equation. Their co re concepts are expressed in Table 2. A later section will discuss their mathematic theories and the practicability for use as an encryption mechanism in details. Table 2: Mechanism Encryption Algorithm Decryption Algorithm Let E be ax 2 + bx + c with a > 0 Convert P to get x C = E(f(x)) = E(ax 2 + bx + c) Let D be g(f(x)) Solve x = − ±√ 2 −4 2 with x ≥ 0 D(x) = D( − ±√ 2 −4 2 ) Convert x to get P Apparently, only when the result of calculation based on the selected mathematical equation can be “inversed” back to its original value, the selected mathematical equation and its inverse are qualified for use as encryption and decryption mechanism. Quadratic Equation and Its Inverse Aufmann, Barker, and Lockwood (2003) defines the term “quadratic equation” as an equation of the standard form ax 2 + bx + c = 0 with a ≠ 0. The following illustrates how to find the roots of x by completing the square. x 2 + x + = 0 x 2 + x = - ( + 2 ) 2 = - + 2 4 2 = 2 −4 4 2 + 2 = ±√ 2 − 4 2 Solving for x then yields the following formula. x = − ±√ 2 −4 2 In mathematics, the inverse of a function f is defined as a function, typically donated by the letter g, such that g(f(x)) = x. Since a quadratic function can be expressed as f(x) = ax 2 + bx + c, its inverse function g of f can be expressed as: g = − ±√ 2 −4 2 In other words, the inverse of the quadratic is the curve formed by the union of the following two functions:

Upload: others

Post on 31-Jul-2020

32 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 334

Lecture #11 Python Programming Project II – Encryption/Decryption

The Proposed

Algorithm

The algorithm contains two segments: encryption and decryption. The encryption algorithm is

performed by a given quadratic equation. The decryption algorithm is the opposite of

encryption, which is performed by the “inverse” of the quadratic equation. Their core concepts

are expressed in Table 2. A later section will discuss their mathematic theories and the

practicability for use as an encryption mechanism in details.

Table 2: Mechanism

Encryption Algorithm Decryption Algorithm

Let E be ax2 + bx + c with a > 0

Convert P to get x

C = E(f(x)) = E(ax2 + bx + c)

Let D be g(f(x))

Solve x = −𝑏 ±√𝑏2−4𝑎𝑐

2𝑎 with x ≥ 0

D(x) = D(−𝑏 ±√𝑏2−4𝑎𝑐

2𝑎)

Convert x to get P

Apparently, only when the result of calculation based on the selected mathematical equation

can be “inversed” back to its original value, the selected mathematical equation and its inverse

are qualified for use as encryption and decryption mechanism.

Quadratic

Equation and Its

Inverse

Aufmann, Barker, and Lockwood (2003) defines the term “quadratic equation” as an equation

of the standard form ax2 + bx + c = 0 with a ≠ 0. The following illustrates how to find the roots

of x by completing the square.

x2 + 𝑏

𝑎x +

𝑐

𝑎 = 0

x2 + 𝑏

𝑎x = -

𝑐

𝑎

(𝑥 +𝑏

2𝑎)

2 = -

𝑐

𝑎 +

𝑏2

4𝑎2 =

𝑏2−4𝑎𝑐

4𝑎2

𝑥 +𝑏

2𝑎=

±√𝑏2 − 4𝑎𝑐

2𝑎

Solving for x then yields the following formula.

x = −𝑏 ±√𝑏2−4𝑎𝑐

2𝑎

In mathematics, the inverse of a function f is defined as a function, typically donated by the

letter g, such that g(f(x)) = x. Since a quadratic function can be expressed as f(x) = ax2 + bx + c,

its inverse function g of f can be expressed as:

g = −𝑏 ±√𝑏2−4𝑎𝑐

2𝑎

In other words, the inverse of the quadratic is the curve formed by the union of the following

two functions:

Page 2: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 335

g = −𝑏+√𝑏2−4𝑎𝑐

2𝑎 and g =

−𝑏−√𝑏2−4𝑎𝑐

2𝑎

The following is an example that explains how the calculation and inversion work. It

necessary to note that when ax2 + bx + c = d with d≠0, the calculation can be performed on ax2

+ bx + (c-d) = 0.

Let f(x) = x2-4x-8, while x = 3.

Therefore, f(3) = 32-4×3-8 = -11

The inversion can be performed by solving x2 - 4x -8 = -11, or

in the standard form x2 -4x + 3 = 0.

Since x = −𝑏±√𝑏2−4𝑎𝑐

2𝑎, x is either 3 or 1.

Design

Concepts

In order to test the proposed encryption and decryption mechanism, the instructor develops a

set of Python applications. The “Encryption” application takes three integer entries, a, b, and

c, to specify a quadratic function f(x) = ax2 + bx + c. It also takes a string input as the

“plaintext”.

When the “Encrypt” button is clicked, the string input will be broken to a character array. A

for..in loop will convert each character to its ASCII code, such as 65 for “A”, and then send

the converted ASCII code to a function named “calculate()” similar to that in one of the above

sample codes. The “calculate()” function will assign the ASCII value to an variable x and

perform a calculation based on the quadratic function f(x) = ax2 + bx + c. The calculated result

will be temporarily appended to a string variable. The for loop will then iterate through the

entire character array until the last character is processed. In order to delimit every adjacent

hash-like value, the instructor chooses comma (,) as delimiter. A comma is placed between

every two-calculated hash-like values. The following figure demonstrates how the applications

work.

Figure 1. Sample Applications

and

During a data exchange scheme, as illustrated by the following figure, the sender must

privately notify the recipient what the single-key is (the key consists of values of chosen a, b,

and c) before the transmission of “plaintexts”. The sender then encrypts the “plaintexts” and

only transmits the “ciphertexts” to the recipient through the Internet. Upon receiving the

“ciphertexts”, the recipient uses the decryption mechanism to obtain the “plaintexts”. During

the transmission, eavesdroppers can capture packets with sniffer tools; however, they must

crack the encryption mechanism to obtain the “plaintexts”.

Figure 2: Data Exchange Scheme

Sender

Recipient

Encrypt Decrypt

eavesdropper

I am

Bob.

36951,

23134,

37582,

42321,

Internet 36951,2

3134,37

582,423

21,3312

I am

Bob.

Privately exchange a, b, c

Page 3: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 336

???

The “Decrypt” application simply inverse the ciphertext to the original plaintext using the

following formulas with a condition that the negative x is eliminated.

x = −𝑏±√𝑏2−4𝑎𝑐

2𝑎

The Encryption

/ Decryption

Mechanism

Seeing that the value of x of a given ax2 + bx + c = 0 can be obtained by the following

formulas, the instructor heuristically evaluates the feasibility to use a quadratic formula for

computing hash-like values.

x = −𝑏±√𝑏2−4𝑎𝑐

2𝑎

The “math” package of Python language provides a function, sqrt(n), to return the square

root of a given number n. By importing the “math” package, programmers can use the sqrt()

function to find the square root of 6.25, as shown below.

import math

print(math.sqrt(6.25))

The above formulas can be expressed as the follows in Python code. It is necessary to note that

programmers can use any programming language to write similar code as well as applications

for encryption and decryption, although the instructor chooses to use Python as the language

for demonstration.

x = (-b + math.sqrt(b*b - 4*a*c)) / 2*a

and

x = (-b – math.sqrt(b*b - 4*a*c)) / 2*a

The following is a simple function named “calculate()” that takes four parameters, x, a, b, and

c, to perform the arithmetic calculation based on the formula f(x) =x2 - 4x – 8 and then return

the result of calculation. The “calculate()” function is a simplified version created to illustrate

the proposed algorithm. Values of a, b, and c are set to be 1, -4, and -8 for the sake of

demonstration. The value of x is set to 65; therefore, the “calculate()” function will convert the

integer 65 (which is the ASCII code of the capital letter ‘A’ and is said to be the “plaintext” in

this case) with the designated quadratic function (f(x) =x2 - 4x – 8) to produce another integer

3957 which is said to be the “ciphertext”.

def calculate(x, a, b, c):

return a*x*x+b*x+c

x = 65

a = 1

b = -4

c = -8

d = calculate(x, a, b, c)

print("f(x) =", d)

or, simply

36951,23134,3

7582,42321,33

124,…..

Page 4: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 337

def calculate(x, a, b, c):

return a*x*x+b*x+c

x = 65

a = 1

b = -4

c = -8

print("f(x) =", calculate(x, a, b, c))

The following inverse() function can solve a quadratic function by letting x2 - 4x - 8 = 3957,

and it will produce two x values, 65 and -61, with only one of them being the “plaintext”. The

reason why the instructor wrote the statement, c=c-d, is because the equation needs to be

converted to x2 - 4x - 8 - 3957 = 0. The value of c was -8 before the conversion, and will be -8

– 3957 after the conversion.

import math

def inverse(a, b, c, d):

# convert ax2+bx+c=d to ax2+bx+c-d=0

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

print("n1 =", n1, "n2 =", n2)

a = 1

b = -4

c = -8

d = 3957

inverse(a, b, c, d)

The above code has a problem of calculation bias. When the value of a is larger than 1 or less

than -1, the returned n1 and n2 are multiples of the given ASCII value. For example, the

equation, 2x2-8x-16, is technically 2 × (x2-4x-8); therefore, f(65) = 2x2-8x-16=7914 (or 2 ×

3957).

During the inverse calculation, the equation 2x2-8x-16 is simplified to x2-4x-8 for the sake of

lowered complexity in calculation, as illustrated below.

f(x) = 2x2-8x-16 = 2 × (x2-4x-8)

thus,

f(65) = 2x2-8x-16 = 2 × (x2-4x-8) = 7914 = 2 × 3957

so,

x2-4x-8 = 3957

The above sample code does not take into consideration how the simplification of equation

during calculation could affect the results. The following version of code illustrates how the

bias of calculation is a problem. It uses f(x) = 2x2-8x-16 as formula, so a is set to be 2, b is -8,

and c is -16, while x is still 65.

import math

def inverse(a, b, c, d):

Page 5: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 338

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

print("n1 =", n1, "n2 =", n2)

a = 2

b = -8

c = -16

d = 7914

inverse(a, b, c, d)

The following is the result of the above code. However, n1 and n2 are expected to be 65 and -

61.

('n1 =', 260.0, 'n2 =', -244.0)

Interestingly, 260 = 65 × 4 and -244 = -61 × 4. In other words, 260 = 65 × 22 and -244 = -61 ×

22. Since a = 2, 260 = 65 × a2 and -244 = -61 × a2. The following is the code that can avoid

such calculation bias.

n1 = n1 / (a*a);

n2 = n2 / (a*a);

Additionally, since ASCII code can only be a positive integer between 0 and 255; therefore,

the negative value (such as -61) is eliminated and 65 is the “plaintext”. The following is a

revised version that will just return the positive value of x and ignore the negative one. It also

eliminates the possible calculation bias.

import math

def inverse(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (n1 < 0): return n2

else: return n1

a = 1

b = -4

c = -8

d = 3957

print("x =", inverse(a, b, c, d))

Both n1 and n2 must be integers because values of ASCII codes are integers. The following

could provide some sort of insurance because the “int()” function can convert a floating-point

value to an integer.

if (n1 < 0): return int(n2)

else: return int(n1)

The following is functionally equivalent to the above code, although their logics could seem to

be reversed. By the way, ASCII code 0 is defined as NULL, which is typically not used.

Therefore, the cases of (n1 == 0) or (n2 == 0) can be omitted in this program.

Page 6: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 339

if (n1 > 0): return int(n1)

else: return int(n2)

The following place both the “calculate()” and “inverse()” functions in one single Python

script file. It also uses the input() function to take user inputs from keyboard, so the values of

x, a, b, and c are provided by the user (and later serves as the “private key”).

import math

def calculate(x, a, b, c):

return a*x*x+b*x+c

def inverse(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (n1 < 0): return n2

else: return n1

x = int(input("Enter the ASCII code of a character: "))

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of c: "))

d = calculate(x, a, b, c)

print("ciphertext =", d)

print("plaintext =", inverse(a, b, c, d))

The above coding activity, which is tested in Learnin Activity #1, lead the instructor to find

two interesting phenomena that requires programmer’s attention.

• When a is positive (a>0), n1 is always the desired inversed value. When a is negative

(a<0), n2 is always the desired inversed value.

• When a is greater than 1 or less than -1, the desired inversed value is either n1/a2 or n2/a2.

With the above interesting phenomena in mind, the following is another way to select the right

option: n1 or n2.

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

The following is functionally equivalent to the above. By definition, a of a quadratic equation,

ax2 + bx + c = 0, cannot be 0. The case, (a == 0), simply does not exist.

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a < 0): return n2

else: return n1

The following is the revised version that reflects the above two phenomena. The instructor

purposely simplifies the code to explain how the solution works. Experienced programmer can

optimize the following code for fast performance and less resource-consumption.

Page 7: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 340

import math

def calculate(x, a, b, c):

return a*x*x+b*x+c

def inverse(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

x = int(input("Enter the ASCII code of a character: "))

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of c: "))

d = calculate(x, a, b, c)

print("ciphertext =", d)

print("plaintext =", inverse(a, b, c, d))

While the above program proves that the “inverse” operation of a user-selected single

quadratic equation is feasible, the following program proves the applicability for using it to

produce hash-like values. It is necessary to note that the identifier of “calculate()” function

changes to “getCipher”, and the identifier of “inverse()” to “getPlaintext”.

import math

def getCipher(x, a, b, c):

return a*x*x+b*x+c

def getPlaintext(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

a = 3

b = 7

c = 19

d = 0;

for x in range(256):

d = getCipher(x, a, b, c)

print("ASCII =", x)

print("ciphertext =", d)

print("plaintext =", getPlaintext(a, b, c, d))

The above code is tested in Learning Activity #2.

Page 8: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 341

Encrypt a

phrase or a

sentence

In Python, a string literal is considered a List of characters; therefore, programmers can simply

pass a string to the list() function to convert a string literal to a List of characters. The

following demonstrates how the conversion works.

>>> s = "Apple"

>>> l = list(s)

>>> print(l)

['A', 'p', 'p', 'l', 'e']

>>> print(l[0], l[1], l[2], l[3], l[4])

('A', 'p', 'p', 'l', 'e')

The following is a simple code that will take a string literal (such as “Apple”) from the user as

the plaintext and convert it to a List of character named “arrChar”. The for..in loop will

retrieve every element of the “arrChar” List and display them on screen one by one. The

variable “ch” is a delegate of elements in “arrChar”. During each iteration, “ch” represents an

element of “arrChar”.

plaintext = input("Enter a phrase: ")

arrChar = list(plaintext)

for ch in arrChar:

print(ch)

In Python, the ord() function returns the ASCII value of a character, as shown below. The

chr() function, on the other hand, converts an ASCII value to a character.

>>> ord('a')

97

>>> chr(97)

'a'

The following code, as a revised version, will convert every element in the “arrChar” List to

the ASCII value.

plaintext = input("Enter a phrase: ")

arrChar = list(plaintext)

for ch in arrChar:

print(ord(ch))

The following is a sample output of the above code. It also illustrates how a given phrase (such

as “Apple”) is converted to a list of ASCII values.

Enter a phrase: Apple

65

112

112

108

101

The following combines the “getCipher()” function with the above sample codes. The

“plaintext” variable keeps a string literal given by the user through keyboard. The list()

function converts the string literal to a List of characters named “arrChar”. Values of a, b, and

c are given the user through keyboard, while the value of x is provided by the “ch” variable of

the for..in loop. During an iteration, the ord() function will convert the current value of “ch” to

it ASCII value, then call the “getCipher()” function to perform a calculation of ax2+bx+c and

return the calculation result to “d”. The value of “d” will be converted to a string literal by

“str()” function and appended to the variable “cipher” with an additional character “,”. The

Page 9: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 342

addition comma (“,”) will serve as delimiter. Finally, the program will print the concatenated

string literal (stored in “cipher”).

def getCipher(x, a, b, c):

return a*x*x+b*x+c

###### handle user inputs ######

cipher = ""

plaintext = input("Enter a phrase: ")

arrChar = list(plaintext) ## convert to List of characters

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of c: "))

### convert character to ASCII ###

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

cipher += str(d) + ","

print(cipher)

The following is the sample output of the above code. The phrase (assuming it is a password)

“Megumi” is converted to a ciphertext: “16537,28945,30135,39137,33849,31349,”.

Enter a phrase: Megumi

Enter value of a coefficient: 3

Enter value of b coefficient: -17

Enter value of c coefficient: 59

16537,28945,30135,39137,33849,31349,

The above code has a small “bug” that needs the programmer’s attention. At the end of the

ciphertext, there is an unwanted comma (“,”) that should be remove. The following dashed

line indicates the unwanted comma.

16537,28945,30135,39137,33849,31349,

In Python, the len() function can return the total number of elements in a List. The following

statement will determine the index of the last element of the “arrChar” array and assigns that

value to the “last” variable.

last = len(arrChar) - 1

The following is the revised code of the for..in loop. The newly added if statement instructs the

program not to append a comma (“,”) when the iteration is working on the last element of the

“arrChar” array; otherwise, append a comma.

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

if (ch == arrChar[last]):

cipher += str(d)

else:

cipher += str(d) + ","

Page 10: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 343

The above code, however, has another bug that must be removed. In the above code, the

expression, (ch == arrChar[last]), could encounter a situation in which any character

in the phrase is the same as the last character. For example, in the phrase “Bigger River”, the

last character is “r” while there is another “r” in the phrase. In this case, both “r” will not be

appended with the comma.

The following is the solution of the above problem. It uses a variable named “counter” to

count if “ch” is representing the last character of the phrase. Since the index of the first

element of “arrChar” List is 0, the initial value of “counter” should be 0. During each iteration,

the value of “counter” will increase by 1.

### convert character to ASCII ###

last = len(arrChar) - 1

counter = 0

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

if (counter == last):

cipher += str(d)

else:

cipher += str(d) + ","

counter=counter+1

The following is the revised complete code. It will produce an output similar to

“16537,28945,30135,39137,33849,31349” which does not has the ending comma.

def getCipher(x, a, b, c):

return a*x*x+b*x+c

###### handle user inputs ######

cipher = ""

plaintext = input("Enter a phrase: ")

arrChar = list(plaintext) ## convert phrase to List of

characters

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of c: "))

### convert character to ASCII ###

last = len(arrChar) - 1

counter = 0

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

if (counter == last):

cipher += str(d)

else:

cipher += str(d) + ","

counter=counter+1

Page 11: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 344

print(cipher)

The above code is functionally sufficient to serve as the “encryption application”. It can

encrypt a given phrase to a list of scrambled values called “ciphertext” with the value of a, b,

and c being the “private key”. According to the above example, the “private key” can be

expressed as (3, -17, 59) while the ciphertext is “16537,28945,30135,39137,33849,31349,”.

Decrypt the

ciphertext

In Python, the split() function can return a list of strings by breaking the given string using the

specified delimiter. The output of splitting is a List of strings. The following example

demonstrates how to use a comma (“,”) as the delimiter to break a given string literal to a List

of strings.

>>> s = "16537,28945,30135,39137,33849,31349"

>>> l = s.split(',')

>>> print(l)

['16537', '28945', '30135', '39137', '33849', '31349']

>>> print(l[3])

39137

The following demonstrates how to use the “split()” function to break two string literals: one is

the ciphertext, the other is the “private key”. By the way, the “private key” will be entered by

the user in the format similar to: 3,-17,59. The string literal of ciphertext will be split to a

List of string type named “arrString”, while the string literal of the “private key” is split to

another string List named “pk”.

ciphertext = "16537,28945,30135,39137,33849,31349"

arrString = ciphertext.split(',')

privateKey = input("Enter the private key: ")

pk = privateKey.split(',')

By the way, the value of a, b, and c are int type. It is necessary to use the int() function to

convert them from string to int type. The value of a will come from the first element of the

“pk” List and is denoted as pk[0]. The value of b will come from the second element of the

“pk” List and is denoted as pk[1].

a = int(pk[0])

b = int(pk[1])

c = int(pk[2])

The following is a for..in loop. During every iteration, it will retrieve an element from the

“arrString” List (represented by “str”), convert the retrieve string literal (such as “16537”) to

an integer using the “int()” function and assign the converted integer to “d”, and then call the

“getPlainTet()” function by passing values of a, b, c, and d to get the positive value of x (an

ASCII code). Finally, the chr() function will convert the ASCII value to its corresponding

character. The character will be appended to a variable named “plaintext”.

for str in arrString:

d = int(str)

plaintext += chr( int(getPlaintext(a, b, c, d)) )

The following statement will display the appended string literal on screen and that string is the

original phrase known as “plaintext”.

print(plaintext)

The following is the complete code.

Page 12: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 345

import math

def getPlaintext(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

###### handle user inputs ######

plaintext = ""

ciphertext = "16537,28945,30135,39137,33849,31349"

arrString = ciphertext.split(',')

privateKey = input("Enter the private key: ")

pk = privateKey.split(',')

a = int(pk[0])

b = int(pk[1])

c = int(pk[2])

### convert ASCII to character ###

for str in arrString:

d = int(str)

plaintext += chr( int(getPlaintext(a, b, c, d)) )

print(plaintext)

The above code is functionally sufficient to serve as the “decryption application”.

The GUI

version

To make the “Encrypt” application becomes a GUI-based application, the instructor chooses to

use the input box provided by the “InputBox.py” file as GUI tool to take user inputs; therefore,

the following statement is changed

plaintext = input("Enter a phrase: ")

to

InputBox.ShowDialog("Enter a phrase:")

plaintext = InputBox.GetInput()

Similarly, the following is changed

a = int(input("Enter value of a: "))

to

InputBox.ShowDialog("Enter value of a:")

a = int(InputBox.GetInput())

In order to display the output in a message box, the following is changed

print(cipher)

Page 13: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 346

to

###### Message Box Code ######

from tkinter import *

root = Tk()

root.title('Message Box')

Label(root, justify=LEFT, text = cipher, width=60,

wraplength=360).grid()

root.mainloop()

The instructor also adds the following statement, so the private key will be displayed in the

message box.

cipher += "\n\nPrivacy Key: (" + str(a) + "," + str(b) + "," +

str(c) +")"

Additionally, the following is added to the code, so the ciphertext will also be saved to a file

named “encrypt.txt”.

#### write cipher to a file ####

encfile = open("encrypt.txt",'w')

encfile.write(cipher)

encfile.close()

At the Decrypt application side, the following line is changed

ciphertext = input("Enter the ciphertext: ")

to

InputBox.ShowDialog("Enter the ciphertext:")

ciphertext = InputBox.GetInput()

The following statement is changed to

privateKey = input("Enter the private key: ")

to

InputBox.ShowDialog("Enter the private key:")

privateKey = InputBox.GetInput()

The following is changed

print(plaintext)

to

###### Message Box Code ######

from tkinter import *

root = Tk()

root.title('Message Box')

Label(root, justify=LEFT, text = cipher, width=60,

wraplength=360).grid()

root.mainloop()

Page 14: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 347

Crackability

The term “crackability” refers to the degree of being “crackable”. The instructor adopts this

term to describe how easy the proposed algorithm can be cracked by “unattempted recipients”.

In order to crack the proposed algorithm, the “unattempted recipients” must satisfy the

following conditions:

• Already know that the algorithm is based on a specially selected quadratic function in the

form of f(x) = ax2 + bx + c.

• Be able to correctly guess what values of a, b, and c are.

• Grasp the patterns used for representing the ciphertexts, such as “24351,29671,28456”,

“24351-29671-28456” “24351:29671:28456”, or simply “243512967128456”.

• The numerical code that represent a character, such as the 65 for “A” in ASCII.

Theoretically and mathematically, the proposed algorithm is crackable. However, it will take a

gigantic amount of computing power and intelligence. The reasons are:

• Values of a, b, and c of the quadratic function f(x) = ax2 + bx + c are randomly picked by

the user each time before the encryption starts. For example, Bob uses f(x) = 3x2 - 4x + 9

and f(x) = -47x2 + 3x + 7 to send his social security number and credit card numbers to

Alice, as shown in Table 3.

Table 3. Sample E(P) = C

Function Plaintext Ciphertext

3x2 - 4x + 9 962-44-8531 9528,8541,7913,5904,7913,7913,5904,9193,8224,7608,7016,

-47x2 + 3x + 7 5168302449753382 -131857,-112693,-136883,-147217,-122087,-108137,-117343,-126925,-126925,-152525,-142003,-131857,-122087,-122087,-147217,-

117343,

• Each character of a sensitive data is an individual P, which must go through E(P) to

produce an individual C. Appendix A provides a sample code which assumes a, b, and c

are all picked from the range 1 to 99. With C being 240076, there are 970299 (or 993)

combinations of (a, b, c). If the sensitive data contains n characters, which means there are

C1, C2, …, Cn, then the total combinations of (a, b, c) is n × 970299. Table 4 is a list of

possible combination if a, b, and c are randomly picked integers from a given range, with

an assumption that there are n character in the “plaintexts”.

Table 4. Possible Combination of (a, b, c, Cn)

Range No. of Combination

-100 ~ 100 2013 × n

-1000 ~ 1000 20013 × n

-10000 ~ 10000 200013 × n

-100000 ~ 100000 2000013 × n

-1000000 ~ 1000000 20000013 × n

Table 5. Sample Computed Results

a b c Result

-47 ...

-47

...

...

-47

3 ...

3

...

...

3

-7 ...

7

...

...

5007

40572/1338642271 ................

5168302449753382

................

................

5268413559754483

• The content of sensitive data also makes the algorithm difficult to crack. For example, it

will take a gigantic effort and intelligence to guess which value in Table 5 is the correct

credit card sent number by Bob.

Interestingly, a mathematical phenomenon could boost the crackability. As shown in Table 6,

square root of integers from 81 to 99 all have a digit 9 as the whole number part, although their

fractional parts are different. When using a “chomp(√𝐶𝑖)” function to remove the fractional

part of √𝐶𝑖, then √𝐶81 = √𝐶82 = … = √𝐶99 = 9. Therefore, -47x2 + 3x + 81, -47x2 + 3x +

82, …, and -47x2 + 3x + 99 could possibly produce the same result. This phenomenon is

Page 15: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 348

known as the “precision issue”, which may vanish when the value of Ci is a larger integer,

such as 8215.

Table 6. Precision Issue in Square Root

Ci √𝑪𝒊 Ci √𝑪𝒊 Ci √𝑪𝒊

81

82

83

84

...

95

96

97

98

99

9.0

9.05538513813

9.11043357914

9.16515138991

.............

9.74679434480

9.79795897113

9.84885780179

9.89949493661

9.94987437106

8100

8200

8300

8400

...

9500

9600

9700

9800

9900

90.0

90.5538513813

91.1043357914

91.6515138991

.............

97.4679434480

97.9795897113

98.4885780179

98.9949493661

99.4987437106

810000

820000

830000

840000

...

950000

960000

970000

980000

990000

900.0

905.538513813

911.043357914

916.515138991

.............

974.679434480

979.795897113

984.885780179

989.949493661

994.987437106

A later section will discuss about how to programmatically avoid this phenomenon.

Optimization

As stated early, the instructor simplifies the above sample code in order to clearly illustrate the

encryption and decryption mechanisms. Programmers can optimize the code in five aspects:

(a) resource utilization, (b) processing speed, (c) length of allowed string for encryption and

decryption, (d) exchange of the single key, and (e) delivery of “ciphertexts”.

ASCII code and Unicode use a series of consecutive integers to represent characters. Each

integer represents a special character, such as 65 for “A”, 66 for “B”, and 67 for “C”. As

demonstrated in a previous section, using a set of relatively small consecutive integers to

present character can cause the “precision issue”. Programmers can randomly assign numerical

code to each character as demonstrated in Table 7. The larger the number the more secured the

proposed algorithm could be.

Table 7. Randomly Assigned Numerical Code Char A B C D E F G H I J K L M

Code 5305 4427 6512 7243 3195 2781 6236 4813 5418 2149 7743 4185 2134

Char N O P Q R S T U V W X Y Z

Code 4320 2443 1624 9352 4601 8180 1314 2238 8166 3754 6902 3493 8522

Char a b c d e f g h i j k l m

Code 1810 7456 9064 3301 1487 1423 7188 3015 5324 1144 2611 4231 8743

Char n o p q r s t u v w x y z

Code 3481 2192 6624 5727 4618 2148 1079 5240 4217 7094 6631 9095 3784

Char 0 1 2 3 4 5 6 7 8 9 ! @ #

Code 1817 6456 5639 3681 1485 7423 4852 3715 2324 1674 2619 4298 8753

Char $ % ^ & * ( ) - + = < > ?

Code 5269 3591 8024 1983 7956 6393 5282 1714 1312 4645 7978 1026 6637

Char { } [ ] | \ , . / ~ ` ;

Code 1658 4237 2181 3846 5037 8561 4431 5967 8064 6239 1678 9671 4538

The following is the sample code that creates a function named “ord2()” that can return the

value assigned to a character based on the above table.

def chr2(c):

if (c == 'A'): return 5305

if (c == 'B'): return 4427

if (c == 'C'): return 6512

Page 16: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 349

....

if (c == 'Z'): return 8522

if (c == 'a'): return 1810

if (c == 'b'): return 7456

...

if (c == 'a'): return 7456

...

if (c == '?'): return 6637

The instructor prepares a Python file named “EncCodes.py” that can be imported to a Python

script to use the above “ord2()” function. Students will need to import the library file using the

following statement.

import EncCodes

The following demonstrates how to use the “ord2()” provided by the “EncCodes” module to

get the above assignment value to a character. The output of the following is 1810 because ‘a’

is assigned 1810 as value according to Table 7.

print(EncCodes.ord2('a'))

The following illustrates how to modify the source code of one of the learning activities to

adopt the randomly generated numerical codes to increase the complexity of the encryption

algorithm and reduce the crackability.

#### Encrypt ######

import InputBox

import EncCodes

..........

..........

for ch in arrChar:

x = EncCodes.ord2(ch)

d = getCipher(x, a, b, c)

In the “EncCodes.py” file, there is a “char2()” function which is created to inverse the “ord2()”

function. The following illustrates how the “char2()” function works.

def chr2(n):

if (n == 5305) : return 'A'

if (n == 4427) : return 'B'

.........

.........

if (n == 9671) : return '`'

if (n == 4538) : return ';'

The following illustrates how to use the “char2()” function. The output is the character “h”

because the assigned numerical code of “h” is 3015.

print(EncCodes.chr2(3015))

The following illustrates how to modify the source code of one the learning activities to adopt

the “char2()” function for decrypting the ciphertext.

for str in arrString:

d = int(str)

plaintext += EncCodes.chr2( int(getPlaintext(a, b, c, d)) )

Review

Question

1. Given a quadratic function, ax2 + bx + c = 0, which is a valid solution of x if written in

Python?

Page 17: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 350

A. (b - math.sqrt(b*b - 4*a*c)) / 2*a

B. (b - math.sqrt(b*b - 4*a*c)) / 2*a*a

C. (-b + math.sqrt(b*b - 4*a*c)) / 2*a

D. (-b + math.sqrt(b*b - 4*a*c)) / 2*a*a

2. Given a quadratic function, f(x) = 3x2 + 5x - 69 , which function can return the value of

f(65)?

A. def getF(x): return 2*x*x+5*x-69

B. def getF(x): return a*x*x+b*x+c

C. def getF(x, a, b, c): return 2*x*x+5*x-69

D. def getF(x, a, b, c): return a*x*x+b*x+c

3. Which can convert the equation c=d to c-d=0 if written in Python?

A. c=d

B. c+=d

C. c=c-d

D. d=d-c

4. Given the following code, what is the output of calc(4, 2)?

def calc(n1, a): n1 = n1 / (a*a)

A. 1

B. 2

C. 4

D. 0

5. Given the following string literal, which can break the string literal into a Python list of

characters?

s = "cash"

A. c = list(s)

B. c = arr(s)

C. c = arrChar(s)

D. c = s

6. Given the following code, what is the output of l[3]?

s = "16537,28945,30135,39137,33849,31349"

l = s.split(',')

A. 39137

B. 30135

C. 28945

D. 16537

7. Given the following code, which can display the letter "H"?

str = "P-A-T-H"

s = str.split('-')

A. s[0]

B. s[1]

C. s[2]

D. s[3]

Page 18: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 351

8. Which is a sample Python statement that can open and create a text file named "apple.txt"

for saving data?

A. f = open("apple.txt")

B. f = open("apple.txt",'w')

C. f = open('w', "apple.txt")

D. f = open("apple.txt",'save')

9. Given the following code, what is the possible outcome?

print(ord('A'))

A. ord('A')

B. 65

C. A

D. 'A'

10. Given the following code, which is the output of the statement, print(chr2(6))?

def chr2(c):

if (c == 'A'): return 5305

if (c == 'a'): return 4437

if (c == '6'): return 1324

if (c == '5'): return 2674

A. 1324

B. 6

C. chr2(6)

D. '6'

Page 19: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 352

Lab #11 Encryption and Decryption Applications

Learning Activity #1:

1. Open the Command Prompt (or Terminal Emulator for Linux user).

2. Change to “cis247” directory.

3. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_1.py” with the following

content:

import math

def calculate(x, a, b, c):

return a*x*x+b*x+c

def inverse(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a)

n2 = n2 / (a*a)

if (n1 < 0): return int(n2)

else: return int(n1)

x = int(input("Enter the ASCII code of a character: "))

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of d: "))

d = calculate(x, a, b, c)

print("ciphertext =", d)

print("plaintext =", inverse(a, b, c, d))

4. Test the program. Using 67 for x (ASCII code), 2 for a, -17 for b, and 94 for c to form the formula: f(x) = 2x2-

17x+94. The following is the sample output.

Enter the ASCII code of a character: 67

Enter value of a: 2

Enter value of b: -17

Enter value of d: 94

ciphertext = 7933

plaintext = 67

5. Download the “assignment template”, and rename it to lab11.doc if necessary. Capture a screen shot similar to

the above and paste it to a Microsoft Word document named “lab11.doc” (or .docx).

Learning Activity #2

1. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_2.py” with the following

content:

import math

def getCipher(x, a, b, c):

or: if (n1 > 0): return int(n1)

else: return int(n2)

Page 20: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 353

return a*x*x+b*x+c

def getPlaintext(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a < 0): return int(n2)

else: return int(n1)

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of c: "))

for x in range(256):

d = getCipher(x, a, b, c)

print("ASCII =", x)

print("ciphertext =", d)

print("plaintext =", getPlaintext(a, b, c, d))

2. Test the program.

Enter value of a: 3

Enter value of b: 7

Enter value of c: 19

ASCII = 0

ciphertext = 19

plaintext = 0.0

ASCII = 1

.........

.........

ASCII = 255

ciphertext = 196879

plaintext = 255.0

3. Capture a screen shot similar to the above and paste it to a Microsoft Word document named “lab11.doc”

(or .docx).

Learning Activity #3

1. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_3.py” with the following

content:

import math

def getCipher(x, a, b, c):

return a*x*x+b*x+c

def getPlaintext(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

######### encryption

or: if (a > 0): return int(n1)

else: return int(n2)

Page 21: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 354

plaintext = input("Enter a phrase: ")

arrChar = list(plaintext) ## convert to List of characters

a = int(input("Enter value of a: "))

b = int(input("Enter value of b: "))

c = int(input("Enter value of c: "))

cipher = ""

### convert character to ASCII ###

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

cipher += str(d) + ","

print(cipher)

######## decryption

arrString = cipher.split(',')

plaintext = ""

for str in arrString:

if (str != ''):

d = int(str)

plaintext += chr( int(getPlaintext(a, b, c, d)) )

print(plaintext)

4. Test the program.

Enter a phrase: Bob sent a message to Alice

Enter value of a: 3

Enter value of b: 7

Enter value of c: -19

13511,37721,29479,3277,40461,31291,37051,41

161,3277,28887,3277,36387,31291,40461,40461

,28887,32529,31291,3277,41161,37721,3277,13

111,35729,33791,30077,31291,

Bob sent a message to Alice

5. Capture a screen shot similar to the above and paste it to a Microsoft Word document named “lab11.doc”

(or .docx).

Learning Activity #4: Two separated applications

1. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_4.py” with the following

content:

#### Encrypt ######

def getCipher(x, a, b, c):

return a*x*x+b*x+c

###### handle user inputs ######

cipher = ""

plaintext = input("Enter a phrase: ")

arrChar = list(plaintext) ## convert phrase to List of characters

a = int(input("Enter value of a: "))

Page 22: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 355

b = int(input("Enter value of b: "))

c = int(input("Enter value of d: "))

### convert character to ASCII ###

last = len(arrChar) - 1

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

if (ch == arrChar[last]):

cipher += str(d)

else:

cipher += str(d) + ","

print(cipher)

2. Test the program.

Enter a phrase: This is a secret.

Enter value of a: -7

Enter value of b: 24

Enter value of d: 193

-47183,-73023,-74462,-89622,-6207,-74462,-89622,-

6207,-63342,-6207,-89622,-68790,-66038,-88043,-

68790,-91215,-13515

3. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_4_1.py” with the following

content:

### Decrypt ####

import math

def getPlaintext(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

###### handle user inputs ######

plaintext = ""

ciphertext = input("Enter the ciphertext: ")

arrString = ciphertext.split(',')

privateKey = input("Enter the private key: ")

pk = privateKey.split(',')

a = int(pk[0])

b = int(pk[1])

c = int(pk[2])

### convert ASCII to character ###

for str in arrString:

d = int(str)

plaintext += chr( int(getPlaintext(a, b, c, d)) )

Page 23: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 356

print(plaintext)

4. Test the program.

Enter the ciphertext: -47183,-73023,-74462,-89622,-

6207,-74462,-89622,-6207,-63342,-6207,-89622,-68790,-

66038,-88043,-68790,-91215,-13515

Enter the private key: -7,24,193

This is a secret.

5. Capture a screen shot similar to the above and paste it to a Microsoft Word document named “lab11.doc”

(or .docx).

Learning Activity #5

1. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_5.py” with the following

content:

#### Encrypt ######

import InputBox

def getCipher(x, a, b, c):

return a*x*x+b*x+c

###### handle user inputs ######

cipher = ""

InputBox.ShowDialog("Enter a phrase:")

plaintext = InputBox.GetInput()

arrChar = list(plaintext) ## convert phrase to List of characters

InputBox.ShowDialog("Enter value of a:")

a = int(InputBox.GetInput())

InputBox.ShowDialog("Enter value of b:")

b = int(InputBox.GetInput())

InputBox.ShowDialog("Enter value of c:")

c = int(InputBox.GetInput())

### convert character to ASCII ###

last = len(arrChar) - 1

counter = 0

for ch in arrChar:

x = ord(ch)

d = getCipher(x, a, b, c)

if (counter == last):

cipher += str(d)

else:

cipher += str(d) + ","

counter=counter+1

cipher += "\n\nPrivacy Key: (" + str(a) + "," + str(b) + "," + str(c) +")"

#### write cipher to a file ####

encfile = open("encrypt.txt",'w')

encfile.write(cipher)

Page 24: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 357

encfile.close()

###### Message Box Code ######

from tkinter import *

root = Tk()

root.title('Message Box')

Label(root, justify=LEFT, text = cipher, width=60, wraplength=360).grid()

root.mainloop()

2. Test the program. Record the private key.

3. Use Windows Explorer to go to the “CIS247” directory to find the “encrypt.txt” file, and then open it with

Notepad. The ciphertext should be saved in the file, as shown below.

4. Use Notepad (or “gedit” for Linux user) to create a new text file named “lab11_5_1.py” with the following

content:

### Decrypt ###

import InputBox

import math

def getPlaintext(a, b, c, d):

c=c-d;

n1 = (-b+math.sqrt(b*b-4*a*c))/2*a;

n2 = (-b-math.sqrt(b*b-4*a*c))/2*a;

n1 = n1 / (a*a);

n2 = n2 / (a*a);

if (a > 0): return n1

else: return n2

###### handle user inputs ######

plaintext = ""

InputBox.ShowDialog("Enter the ciphertext:")

ciphertext = InputBox.GetInput()

arrString = ciphertext.split(',')

InputBox.ShowDialog("Enter the private key:")

Page 25: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 358

privateKey = InputBox.GetInput()

pk = privateKey.split(',')

a = int(pk[0])

b = int(pk[1])

c = int(pk[2])

### convert ASCII to character ###

for str in arrString:

d = int(str)

plaintext += chr( int(getPlaintext(a, b, c, d)) )

###### Message Box Code ######

from tkinter import *

root = Tk()

root.title('Message Box')

Label(root, justify=LEFT, text = plaintext, width=60, wraplength=360).grid()

root.mainloop()

5. Test the program. Use Notepad to open the encrypt.txt file to copy and paste the ciphertext.

6. Capture a screen shot similar to the above and paste it to a Microsoft Word document named “lab11.doc”

(or .docx). [Feel free to convert the Word document to a .pdf file.]

Submittal

1. Upon the completion of learning activities, compress the following files and name the zipped file lab11.zip.

• lab11_1.py

• lab11_2.py

• lab11_3.py

• lab11_4.py

• lab11_5.py

• lab11.doc (or .docx or .pdf)

2. Upload the zipped file as response to Question 11 (available at Blackboard).

Programming Exercise #11_1:

1. Make a copy the “lab11_5.py” file and rename it to “encryptapp.py”.

2. Make a copy the “lab11_5_1.py” file and rename it to “decryptapp.py”.

3. Download the “EncCodes.zip” file and extract it to the directory where you store both “encryptapp.py” and

“decryptapp.py”.

4. Review the “Optimization” section of the lecture note, and then use the “ord2()” function provided by the

“EncCodes.zip” file to replace the “ord()” function in the “encryptapp.py” file. Similarly, replace the “chr()”

function of the “decryptapp.py” with “chr2()”.

Page 26: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 359

5. Make sure the output look similar to the followings.

6. Download the “programming exercise template”, and then rename it to ex11.doc. Copy and paste the source

code(s) to the template. Capture a screen shot similar to Fig. ex11 and paste it to a Microsoft Word document

named ex11.doc (or ex11.docx). [Feel free to convert the Word document to a .pdf file.]

Programming Exercise #11_2:

1. Make a copy of the “lab11_3.py” and rename it to “ex11_2.py”. Then, add the following two lines to the very

beginning of the file. Be sure to replace YourNameHere with your full name.

# Student: YourNameHere

# Programming Exercise: 11_2

2. Write appropriate Python code to enforce that the given values of a, b, and c must satisfy the condition, b2-4ac ≥ 0, display a

rejection message if the condition is not made. [For example, when a = 2, b =3, and c = 7, b2-4ac =32-4×2×7 =9 – 56 = -47.

Then, √𝑏2 − 4𝑎𝑐 = √−47 which is not mathmetically computable.]

3. In an appropriate location, ask the user to enter an integer value (between 10 and 99) as “key”.

4. Modify the following code to strengthen the encryption algorithm by adding the value of “key” to the ASCII

code before assigning the calculated result to the “x” variable.

x = ord(ch)

5. Modify the following code by subtracting the value of “key” from the value returned by the “getPlainText()”

function.

plaintext += chr( int(getPlaintext(a, b, c, d)) )

6. Test the program using a = 2, b =3, and c = 7.

Enter a phrase: A friend in need is a friend indeed

Enter value of a: 2

Enter value of b: 3

Enter value of c: 7

Error!! The given a, b, and c is not a computable combination.

7. Test the program by using a = 3, b = 7, c = 10, key = 67. Make sure the output looks similar to the following.

Enter a phrase: A friend in need is a friend indeed

Enter value of a: 3

Page 27: Python Programming Project II Encryption/Decryptionstudents.cypresscollege.edu/cis247/lc11.pdf · Python Programming – Penniel P. Wu, PhD. 306 Lecture #11 Python Programming Project

Python Programming – Penniel P. Wu, PhD. 360

Enter value of b: 7

Enter value of c: -10

Enter value of key [10-99]: 67

53186,30086,86856,99540,89946,85838,95216,84826,30086,89946,95216,30086,95216,85838

,85838,84826,30086,89946,100636,30086,81826,30086,86856,99540,89946,85838,95216,848

26,30086,89946,95216,84826,85838,85838,84826,

A friend in need is a friend indeed

8. Capture a screen shot similar to the above figure(s) and paste it to a Microsoft Word document named ex11.doc

(or ex11.docx). [Feel free to convert the Word document to a .pdf file.]

Submittal (Please read the instructions carefully)

1. Create a .zip file named “ex11.zip” containing ONLY the following self-executable files and Word document.

Be sure to copy and paste your source codes to the Word document.

• ex11_1.py

• ex11_2.py

• ex11.doc (or .docx, or .pdf) [you may receive zero point if this word document is missing]

2. Upload the zip file as response of Question 12.

Grading criteria:

You will earn credit only when the following requirements are fulfilled. No partial credit is given.

• You successfully submit both source file and executable file.

• Your source code must be fully functional and may not contain syntax errors in order to earn credit.

• Your code must be fully functional to earn the credit. No partial credit is given.

• You will receive zero points if either .py or .doc (or .docx) file is not submitted.