In life, sometimes we need to encrypt some important files,Python provides easy-to-use cryptographic libraries such as hashlib, base64, etc.

But we can implement a simple file encryption program with the help of heterodyne operations

Basic knowledge

In Python, the iso-or operator is ^, or XOR, which means that the same value is 0 and a different value is 1. Specifically, there are four possibilities: 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0. We can also summarize the rule (where A is 0 or 1): 0 and A iso-or is A itself; 1 and A iso-or is A inverse.

Let us consider the properties satisfied by a binary number:

  • A binary number is a 0 to itself

b ^ b = 0

  • Heterogeneous operations satisfy the exchange law

a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c

  • The difference between 0 and a is a

(a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a

Encryption Operations:

First convert the file into a binary number, then generate a random key of the same length as the binary number, and then perform an alias operation between the binary number and the key to obtain the encrypted binary number.

Decryption operations:

The original binary number is obtained by performing an alias operation between the encrypted binary program and the key, and finally the original binary number is restored to a text file.

Generate a random key:

The secrets library is a pseudo-random number module introduced in Python 3.6, suitable for generating random keys. token_bytes function accepts an int argument specifying the length of a random byte string. int.from_bytes converts the byte string to int, which is the binary number we need.

from secrets import token_bytes

def random_key(length):
    key = token_bytes(nbytes=length)
    key_int = int.from_bytes(key, 'big')
    return key_int
Encryption unit:

The encrypt function takes a str object and returns a tuple (int, int). With the encode method we encode the string into a byte string. int.from_bytes converts the byte string into an int object. Finally, the encrypted text is obtained by performing an alias operation on the binary object and a random key.

def encrypt(raw):
    raw_bytes = raw.encode()
    raw_int = int.from_bytes(raw_bytes, 'big')
    key_int = random_key(len(raw_bytes))
    return raw_int ^ key_int, key_int
Decryption unit:

decrypt takes two int objects, the encrypted text and the random key. The decrypted.bit_length function gets the number of bits of the binary number and divides it by 8 to get the size of the bits. To prevent the binary numbers from 1 to 7 bits from dividing by 8 to get 0, add 7 and then divide by 8. Use the int.to_bytes function to convert the decrypted int object to bytes object. Finally, use the decode method to convert the bytes to strings.

def decrypt(encrypted, key_int):
    decrypted = encrypted ^ key_int
    length = (decrypted.bit_length() + 7) // 8
    decrypted_bytes = int.to_bytes(decrypted, length, 'big') 
    return decrypted_bytes.decode()

Using the above functions, we can easily encrypt and decrypt text files.

>>> raw = 'demo'
>>> encrypted = encrypt(raw)
>>> encrypted
(217447100157746604585...,
 9697901906831571319...)
>>> decrypt(*encrypted)
'demo'

Encrypt text files
path is the address of the file to be encrypted, if no key address is specified, then new directories and files will be created in that directory.

import json
from pathlib import Path

def encrypt_file(path, key_path=None, *, encoding='utf-8'):
    path = Path(path)
    cwd = path.cwd() / path.name.split('.')[0]
    path_encrypted = cwd / path.name 
    if key_path is None:
        key_path = cwd / 'key'
    if not cwd.exists():
        cwd.mkdir()
        path_encrypted.touch()
        key_path.touch()

    with path.open('rt', encoding=encoding) as f1, \
        path_encrypted.open('wt', encoding=encoding) as f2, \
            key_path.open('wt', encoding=encoding) as f3:
        encrypted, key = encrypt(f1.read())
        json.dump(encrypted, f2)
        json.dump(key, f3)

Decrypted files

def decrypt_file(path_encrypted, key_path=None, *, encoding='utf-8'):
    path_encrypted = Path(path_encrypted)
    cwd = path_encrypted.cwd()
    path_decrypted = cwd / 'decrypted' 
    if not path_decrypted.exists():
        path_decrypted.mkdir()
        path_decrypted /= path_encrypted.name
        path_decrypted.touch()
    if key_path is None:
        key_path = cwd / 'key'
    with path_encrypted.open('rt', encoding=encoding) as f1, \
        key_path.open('rt', encoding=encoding) as f2, \
        path_decrypted.open('wt', encoding=encoding) as f3:
        decrypted = decrypt(json.load(f1), json.load(f2))
        f3.write(decrypted)

After executing the encryption and decryption operations, the decrypted file will be the same as the original file, as shown in the following diagram:

Hypothesis

Related articles

Quickly test your Python code with Hypothesis

Testing is important no matter which programming language or framework you use. hypothesis is an advanced testing library for Python. It allows writing test cases with parameters, and then generating easy-to-understand test data that makes the test fail.

mplcyberpunk tutorials

Cyberpunk 2077" is a very popular single-player game ~ The game is set in the year 2077, a highly developed technology but chaotic and disorderly "cyberpunk" city. In this world, although the technology is highly developed, but the standard of living of

Heartrate: Real-time Visualization for Python Execution

Heartate - Track programs like a heart rate,Heartrate is a Python tool library that allows you to visualize the execution of Python programs in real time. Monitoring a running Python program is shown in the following figure.

Implementing reverse proxies with Django only

When you think of reverse proxies, you say nginx. nginx is the ideal reverse proxy tool. But now the conditions are tough. The server doesn't have nginx and doesn't have root privileges, which means you can't compile and install nginx, and only one port,

What does join mean in python?

Python has two functions .join() and os.path.join(), which do the following: . join(): Concatenate string arrays. Concatenates the elements of a string, a tuple, and a list with the specified characters (separator) to generate a new string os.path.join()

Add new content to the python dict

Adding new content to a dictionary is done by adding new key/value pairs, modifying or deleting existing key/value pairs as in the following examples

How to delete elements in python dict

clear() method is used to clear all the data in the dictionary, because it is an in-place operation, so it returns None (also can be interpreted as no return value)

python crawler how to get cookies

Cookie, refers to the data (usually encrypted) that some websites store on the user's local terminal in order to identify the user and perform session tracking. For example, some websites require login to access a page, before login, you want to grab the

How OpenCV tracks objects in video

Each frame of the video is a picture, tracking an object in the video, decomposition down, in fact, is to find that object in each frame of the picture.