SoFunction
Updated on 2024-11-13

Python Programming Cryptography File Encryption and Decryption Code Analysis

In previous chapters, programs were written that could only manipulate a relatively small amount of information, which was often written directly into the code in the form of strings. However, the programs in this chapter can encrypt and decrypt entire files, which can include thousands of characters in size.

Highlights of the chapter

open() method.

Read and write files.

The write(), close() and read() file object manipulation methods.

() method.

The upper(), lower() and title() string manipulation methods.

Startswith() and endswith() string manipulation methods.

The time module and the () method

1 Plain text file

Programs that replace files only encrypt/decrypt plain text (unformatted text) files, which are files with a .txt extension that do not contain anything other than text data. To write such files, you can choose to use Notepad on Windows, TextEdit on macOS, or gedit on Linux. (Text processing programs such as Word can also generate plain text files, but remember that these files cannot save font styles, font sizes, colors, or any other formatting. ) In addition to the above text editing software, the reader can even use the IDLE text editor, as long as the file is saved with a .txt extension instead of the usual .py.

If you need a sample plain text file, you can download some txt novels from the Internet. It may take a lot of time to manually input the plain text into the program, but if you use a ready-made txt file, the program can complete the encryption operation in a few seconds.

2 Source code for encrypting a file with a substitution cipher

Based on the replacement password test program in the previous two chapters, the replacement password program for files introduces transposition and these two files so that the functions encryptMessage() and decryptMessage() can be called. Therefore, this new program can be written without having to retype the code for the two functions.

Check File ▶ New File to open a new edit window, enter the following code into the edit window and store it as. Next, visit the companion resource for this book to download a file named and place it under the same path as the py file, and press F5 to run the program.

 # Replacement of password encryption/decryption files
 # /crackingcodes/ (BSD Licensed)
 import time, os, sys, transpositionEncrypt, transpositionDecrypt
 def main():
 inputFilename = ''
 # Note that if a file with the name outputFilename already exists, the program
 # Overwrite the file
 outputFilename = ''
 myKey = 10
 myMode = 'encrypt' # Set to 'encrypt' or 'decrypt'
 # If the input file does not exist, the program terminates early
 if not (inputFilename):
 print('The file %s does not exist. Quitting...' % (inputFilename))
 ()
 # If the output file already exists, give the user a chance to quit
 if (outputFilename):
 print('This will overwrite the file %s. (C)ontinue or (Q)uit?' %
(outputFilename))
 response = input('> ')
 if not ().startswith('c'):
 ()
 # Read messages from the input file
 fileObj = open(inputFilename)
 content = ()
 ()
 print('%sing...' % (()))
 # Measurement of time required for encryption/decryption
 startTime = ()
 if myMode == 'encrypt':
 translated = (myKey, content)
 elif myMode == 'decrypt':
 translated = (myKey, content)
 totalTime = round(() - startTime, 2)
 print('%sion time: %s seconds' % ((), totalTime))
 # Write the replaced message to the output file
 outputFileObj = open(outputFilename, 'w')
 (translated)
 ()
 print('Done %sing %s (%s characters).' % (myMode, inputFilename,
len(content)))
 print('%sed file is %s.' % ((), outputFilename))
 # If run (and not introduced as a module), the
 # Call the main() function
 if __name__ == '__main__':
 main()

3 Sample of running the substitution password encryption file program

The output obtained from running is as follows.

Encrypting...
Encryption time: 1.21 seconds
Done encrypting  (441034 characters).
Encrypted file is .

This creates a new file named transposition in the same path as transposition. Open this new file with the IDLE file editor and you will see the encrypted text in the file. It should look like the following.

PtFiyedleo a arnvmt eneeGLchongnes Mmuyedlsu0#uiSHTGA r sy,n t ys
s nuaoGeL
sc7s,
--snip--

Each time a file is encrypted, the result of the encryption can be sent to another person to decrypt it, who will also need the source code of the file replacement program.

To decrypt the ciphertext, you can make the following changes to the source code (in bold) and subsequently run the program again.

 inputFilename = ''
 # If a file with the name outputFilename already exists, the program
 # Overwrite the file
 outputFilename = ''
 myKey = 10
 myMode = 'decrypt' # set to 'encrypt'maybe'decrypt

Running the program at this point creates a new file named in the current folder, the contents of which are identical to the original plaintext.

4 File operations

Before delving into the source code of a file, it is important to first understand how Python operates on files. The 3 steps to reading the contents of a file are opening the file, reading the contents of the file and storing them in a variable, and closing the file. Similarly, to write new content to a file, you must first open (or create) a file, then write new content to it, and finally close the file.

4.1 Opening of documents

Python can open a file for reading and writing content through the open() method, whose first parameter is the filename. When the file to be opened is in the same folder as the Python program, you can use the file name directly, for example, "", if there is such a file in the current folder, the Python command to open it is shown below.

fileObj = open('')

In this way, a file object is stored in the variable fileObj, which is then used for read and write operations.

You can also use the absolute path of the file as the first parameter, so that the name of the folder where the file is located and all of its parent folders need to be included in quotes, for example, something like "C:\\Users\\\Al\\\" (under Windows), or "/Users/Al/" (under macOS and Linux) are absolute paths. Remember, under Windows, you must add an extra backslash before the backslash (/) for escaping.

As an example, if you want to open the file "", you need its path in the form of a string as the first parameter of the open() method (the format of the absolute path is determined by the operating system used).

fileObj = open('C:\\Users\\Al\\')

The file object has a variety of methods for reading, writing, and closing files, which are described in detail below, with the order reversed for ease of illustration.

4.2 Data writing and file closure

For the file encryption program, after reading the text content will need to write the encrypted data into a new file, this time the method used is write().

To use the write() method of a file object, you first need to open the file in write mode, i.e., pass the string 'w' into the open() method as its two parameters. the second parameter of the open() method is a <span style=" color:#20B2AA"; "font-family: Times New Roman,italic_GB2312">optional parameter), which means that the open() method can still work without the second parameter. This means that the open() method can still be called without the second parameter. For example, enter the following code into an interactive runtime environment.

>>> fileObj = open('', 'w')

This line creates a file named "" in write mode, then it can be edited. If a file with the same name exists in the path where the open() method creates the new file, the file with the same name will be rewritten, so you need to be very careful when using the opne() method in write mode.

Once opened in write mode, you can call the write() method, which takes one argument: the contents of the file to be written, stored in a string. Enter the following code into the Interactive Runtime Environment to write the string Hello, world!

>>> ('Hello, world!')13

The code above passes the string Hello, world! as an argument to the write() method, which writes the string to the file and prints the number 13, which represents the number of characters written to the file.

Once the operation on the file has been executed, Python needs to be informed of this by calling the close() method of the file object.

>>> ()

In addition to the write mode, which necessarily overwrites the contents of the original file, there is an append mode, in which a string is added to the end of the existing contents of the file. Although this mode is not used in the programs in this chapter, the reader can attempt to open a file in the additional mode on his own by taking the string 'a' as the second argument to the open() method.

If you encounter an error message ": not readable" when calling the write() method of a file object, it is possible that the file has not been opened in write mode. If the open() method is called without an optional parameter, its default value will be set to write mode ('r'), which only allows the user to call the read() method of the file object.

4.3 Reading files

To verify that the read() method returns everything contained in a file as a string, this section reads a file created with the wirte() method. Run the following code in an interactive environment.

>>> fileObj = open('', 'r')
>>> content = ()
>>> print(content)
Hello world!
>>> ()

The file object created after opening the file is stored in the variable fileObj. If the object exists, you can use the read() method to read the contents of the file and store them in the variable content, and then print the value of the variable. After performing the above operations on the file object, use the close() method to close the file.

If you encounter the error message "IOError: [Errno 2] No such file or directory", please make sure that the file you want to open is in the path that the reader thinks it is, and double-check that the name of the file and the name of the folder are correctly entered. (<span style="color:#20B2AA"; "font-family: Times New Roman,italic_GB2312"> folder that< span style="color:#20B2AA"; "font-family: Times New Roman,italic_GB2312"> path.)

In the program, encryption and decryption of files requires all the open(), write() and close() methods mentioned above.

5 Creating the main() function

The first part of the program should look very familiar. Line 4 is an import statement that introduces the time, os, and sys modules from both the program and the Python library, followed by the main() function, which creates the variables that the program needs to use.

 # Replacement of password encryption/decryption files
 # /crackingcodes/ (BSD Licensed)
 import time, os, sys, transpositionEncrypt, transpositionDecrypt
 def main():
  inputFilename = ''
  # Note that if a file with the name outputFilename already exists, the program
  # Overwrite the file
  outputFilename = ''
  myKey = 10
  myMode = 'encrypt' # Set to 'encrypt' or 'decrypt'

The variable inputFilename stores the string of the filename to be read, and the encrypted (or decrypted) contents are written to a file named after the value of the variable outputFilename. The program involves a substitution cipher that uses an integer as the key and is stored in myKey, and the program requires a variable myMode that stores the string encrypt or decrypt to determine what operation to perform on the file stored in inputFilename. Before reading the inputFilename file, the file is first checked for existence using ().

6 Checking the existence of documents

Reading a file is often harmless, but writing to a file requires more care because calling the open() method in write mode will overwrite the contents of the original file if it already exists. To deal with this potential problem, programs can use the () method to check whether the file to be opened already exists.

6.1 () Methods

The () method takes one argument, either a filename or a path to a file, and returns True if the file exists; otherwise, it returns False.This method is included in the path module, which is included in the os module, so when the os module was introduced, the path module was introduced along with it.

Enter the following code into the interactive runtime environment.

  >>> import os
 ❶ >>> ('')
  False
  >>> ('C:\\Windows\\System32\\') # Windows
  True
  >>> ('/usr/local/bin/idle3') # macOS
  False
  >>> ('/usr/bin/idle3') # Linux
  False

In this example, the () method confirms the existence of the file on the Windows system. Of course, you can only get the above result if you run Python under Windows. Remember, when typing a file path under Windows, escape it by adding another backslash before the backslash. If you are using macOS, only the macOS example in the above code will return True, and similarly on Linux only the last example will return True. If the full path ❶ is not given, Python checks the current working path; for the IDLE Interactive Runtime Environment, the current working path is the folder where Python is installed.

6.2 Checking for the existence of an input file using the () method

Lines 14 to 17 of the program in this chapter use () to check for the existence of the file in inputFilename; without this step, the file used for encryption and decryption cannot be obtained.

14. # If the input file does not exist, the program terminates early
15. if not (inputFilename):
16. print('The file %s does not exist. Quitting...' % (inputFilename))
17. ()

If the file does not exist, the program will pop up a prompt for the user and exit.

7 Using String Methods to Make User Input More Flexible

Next, the program needs to check to see if a file with the same name as outputFilename exists, and if it does, ask the user whether to type c to continue running the program or q to exit the program. Since the user may enter multiple responses, such as c, C, or even the word Continue, the program needs to make sure that it can receive all of these inputs, and more string methods will have to be used to accomplish this.

7.1 upper(), lower() and title() string methods

The upper() and lower() methods can return the string they receive in all uppercase and all lowercase, respectively. Enter the following code into an interactive runtime environment to see how these two methods operate on the same string.

>>> 'Hello'.upper()
'HELLO'
>>> 'Hello'.lower()
'hello'

The lower(), and upper() methods return strings in lower and upper case, and the title() method is similar to them, however, this method returns strings with the first letter of each word capitalized, which means that the first letter of each word in the string is capitalized, and all the rest of the letters are lower case. Enter the following code into the interactive runtime environment.

>>> 'hello'.title()
'Hello'
>>> 'HELLO'.title()
'Hello'
>>> 'extra! extra! man bites shark!'.title()
'Extra! Extra! Man Bites Shark!'

The program in this chapter will use the title() method later in the chapter to format the output.

7.2 The startswith() and endswith() methods

The startwith() method returns True if the string begins with the string specified by the argument. enter the following code into the interactive runtime environment.

 >>> 'hello'.startswith('h')
 True
 >>> 'hello'.startswith('H')
 False
 >>> spam = 'Albert'
 ❶ >>> ('Al')
 True

The startswith() method is case sensitive and can also take multi-character strings ❶.

The endswith() method is used to check whether a string ends with a particular string. Enter the following code into the interactive runtime environment.

 >>> 'Hello world!'.endswith('world!')
 True
❷ >>> 'Hello world!'.endswith('world')
 False

String matches must be word-for-word; note that endswith() returns False because of the missing exclamation point in ❷.

7.3 Using the above string methods in a program

As mentioned before, the program needs to be able to receive all responses that begin with the letter C, regardless of case, which means that the program will need to rewrite the file regardless of whether the user enters a C, continue, c, or any other string that begins with C. Using the lower() and upper() methods gives the program more flexibility in dealing with strings entered by the user.

 # If the output file already exists, give the user a chance to quit
 if (outputFilename):
 print('This will overwrite the file %s. (C)ontinue or (Q)uit?' %
 (outputFilename))
 response = input('> ')
 if not ().startswith('c'):
 ()

On line 23, take the first letter of the string and use the startswith() method to check if it is a C. Since the startswith() method is case sensitive and checks for a lowercase 'c', use the lower() method before calling it to change the response string's first letter so that it remains a lowercase 'c'. If the user does not enter a response that begins with C, the if's conditional statement will get True (because it contains a not), whereupon the () statement is called and the program terminates. Technically, the user doesn't need to type q to exit; any string that doesn't begin with C causes the () method to be called, which causes the program to exit.

8 Reading a file as input

On line 27, the program begins using the file object methods discussed at the beginning of this chapter.

26. # Read messages from the input file
27. fileObj = open(inputFilename)
28. content = ()
29. ()
30.
31. print('%sing...' % (()))

Lines 27-29 open a file with the same name as inputFilename, read its contents and store them in the variable content, and then close the file. After reading the file, line 31 outputs a message to the user informing them that encryption or decryption has begun. Since the variable myMode stores the string encrypt or decrypt, calls the title() string method to convert its first letter to uppercase, and adds the string ing after it, it ends up displaying Encrypting... or Decrypting .....

9 Calculate the time required for encryption/decryption

Fully encrypting/decrypting a file often takes more time than just encrypting/decrypting a short string, and the user may want to know exactly how long the process of encrypting/decrypting a file takes. Programs can use the time module to calculate how long the encryption/decryption process will take.

9.1 The time module and the () method

() method returns the total number of seconds from January 1, 1970, to the current time as a floating-point number called <span style="color:#20B2AA"; "font-family: Times New Roman,italic_GB2312">UNIX timestamp. Enter the following code into the interactive runtime environment and observe the results of the method.

>>> import time
>>> ()
1540944000.7197928
>>> ()
1540944003.4817972

Since () returns a floating point number, it can be accurate to <span style="color:#20B2AA"; "font-family: Times New Roman,italic_GB2312 ">milliseconds. Of course, the time displayed by () is determined by the time the programmer calls it, and it can be difficult to convert it to normal time; for example, it's hard to see that 1540944000.7197928 is Tuesday, October 30, 2018 at about 5:00 PM. However () is well suited to comparing the number of seconds difference between two calls to (), so a program can use it to calculate the running time.

For example, if you follow the code below and subtract the time between the two calls to () in the previous code, you can get the time that elapsed between the two calls.

>>> 1540944003.4817972 - 1540944000.7197928
2.7620043754577637

If you want to write code that operates on dates and times, check out the datetime module.

9.2 Using the () method in a program

On line 34, the () method returns the current time and stores it in a variable named startTime; lines 35 to 38 call encryptMessage() or decryptMessage() depending on whether the value of the variable myMode is encrypt or decrpt.

33. # Measurement of time required for encryption/decryption
34. startTime = ()
35. if myMode == 'encrypt':
36. translated = (myKey, content)
37. elif myMode == 'decrypt':
38. translated = (myKey, content)
39. totalTime = round(() - startTime, 2)
40. print('%sion time: %s seconds' % ((), totalTime))

After the encryption/decryption is complete, line 39 calls the () method again and subtracts startTime from the time of this call, giving the result as the time between two calls to the () method. The () - startTime expression passes the resulting result to the round() method, that is, it rounds it up, since the program does not need to be precise to the millisecond. This integer value is assigned to the variable totalTime. line 40 uses string concatenation and prints for the user the mode the program is in and the amount of time used to encrypt or decrypt.

10 Write output to file

The contents of the encrypted (or decrypted) file are now stored in the variable translated, but this variable is released when the program terminates, so a file is needed to store the string so that the result is saved even if the program stops execution. The code on lines 43 to 45 performs this part of the operation, opening a new file [passing w to the open() method] and calling the write() method of the file object.

42. # Write the replaced message to the output file
43. outputFileObj = open(outputFilename, 'w')
44. (translated)
45. ()

More information is printed next on lines 47 and 48, informing the user of the name of the output file and that the encryption/decryption process is complete.

47. print('Done %sing %s (%s characters).' % (myMode, inputFilename,
 len(content)))
48. print('%sed file is %s.' % ((), outputFilename))

Line 48 is the last line of the main() function.

11 Calling the main() function

Lines 53 and 54 (the two lines that are executed after the execution of the def statement on line 6) call the main() function, provided that the current program is in the running state and not in the referenced state.

51. # If run (and not introduced as a module), the
52. # Call the main() function
53. if __name__ == '__main__':
54. main()

This part is explained in detail in section 7.12.

12 Summary

The program doesn't contain much new except for the open(), read(), write(), and close() functions that help us encrypt large text files on the hard disk. The reader learns how to use the () function to check if a file already exists. Also, as the reader can see, programming can be expanded by introducing functions from previously written programs into a new program, which greatly increases a computer's ability to encrypt information.

In addition to this, the reader learns some useful string methods that make the program more flexible when receiving yoghurt input; the time module also helps to calculate how long the program has been running.

Unlike programs that implement Caesar's cipher, if one wants to use brute-force algorithms to crack a file encrypted by a substitution cipher, there are too many possible keys. But by writing a program that recognizes English (and other meaningless gibberish), the computer can examine thousands of decryption results, ;and determine a key that will successfully decrypt the ciphertext into English. This is covered in detail in Chapter 11.

This article is excerpted from "Python Cryptography Programming 2nd Edition", [US] Al Sweigart, Zheng Xinfang, Zhao Yi Flirt translation.

Easy-to-understand cryptography, bestseller fully upgraded beginner's guide to implementing cryptographic algorithms in Python programming

In this book, you will learn how to create and send ciphertexts by making and breaking ciphers through Python programming! After learning the basics of Python programming, you'll start with a simple program that uses reverse and Caesar ciphers to understand methods for encrypting public keys, which are used to protect the proper functioning of online transactions, including digital signatures and email. In addition, you will learn how to encrypt text using classical ciphers such as substitution ciphers and Virginia ciphers. Each program includes complete code and line-by-line instructions. At the end of the book, you'll learn how to code in Python.

You will also learn the following:

Combining loops, variables, and flow control statements into actual working programs; using dictionary files to detect whether decrypted messages are valid English or gibberish; creating and testing programs to ensure that code is encrypted and decrypted correctly; examples of encoding (cracking) imitation projective ciphers (encrypting a message using modular arithmetic); cracking ciphers using techniques such as brute-force algorithms and frequency analysis

This is the detailed content of Python programming cryptography file encryption and decryption, more information about Python cryptography file encryption and decryption, please pay attention to my other related articles!