# Can Python still work like this? Encrypted file, unbreakable!

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

But for everyday learning, we can use XOR operation to implement a simple file encryption program, thus strengthening our programming ability. Remember to add an asterisk to the public number, so you won't miss the wonderful content.

#### Basic knowledge

In Python, the XOR operator is: ^, which can also be recorded as XOR. Bit-by-bit XOR means that the same value XOR is 0 and the different value XOR is 1. Specifically, there are four possibilities: 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, and 1 ^ 1 = 0. We can also summarize the rules (A is 0 or 1): 0 and A are different or A itself; 1 and A are different or A is opposite.

Let's look at the properties of a binary number satisfying:

• A Binary Number with its own XOR Value of 0

b ^ b = 0

• XOR operation satisfies commutation 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

It is easy to see that the above properties are satisfied for any long binary number.

#### principle

By understanding the nature of XOR operations, the encryption principle is very clear.

##### Encryption operation:

Firstly, the file is converted into binary number, and the random key of the same length as the binary number is regenerated. The binary number and the key are XOR operated to get the encrypted binary number.

##### Decryption operation:

If the encrypted binary program and the key are XOR operated, the original binary number can be obtained. Finally, the original binary number can be restored to a text file.

##### Generate a random key:

secrets library is a pseudo-random number module introduced by Python 3.6, which is suitable for generating random keys. The token_bytes function accepts an int parameter to specify the length of the 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
Python Resource sharing qun 784758214 ,Installation packages are included. PDF，Learning videos, here is Python The gathering place of learners, zero foundation and advanced level are all welcomed.
```
##### Encryption unit:

The encrypt function accepts a str object and returns tuples (int, int). By using the encode method, we encode the string into byte strings. The int.from_bytes function converts the byte string into an int object. Finally, the encrypted text is obtained by XOR operation of binary objects and random keys.

```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 accepts two int objects, encrypted text and random key. Firstly, XOR operations are performed to calculate the proportion of decrypted int objects. The decrypted.bit_length function gives the number of digits of the binary number, divided by 8, to get the specific size of the proportion. In order to prevent, 1 - 7 bits of binary digits divide by 8 to get 0, so add 7, and then divide by 8. Use the int.to_bytes function to convert the decrypted int object into bytes object. Finally, byte strings are converted into strings by decode method.

```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 = 'Draw a picture of the spring breeze and return to the night.'
>>> encrypted = encrypt(raw)
>>> encrypted
(217447100157746604585...,
9697901906831571319...)
>>> decrypt(*encrypted)
'Draw a picture of the spring breeze and return to the night.'

```

#### Encrypted text file

path is the address of the file to be encrypted. If the key address is not specified, a new directory and file will be created in the 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:
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: