vb異或加密和解密 用Python加密檔案

2021-10-11 23:54:22 字數 3682 閱讀 2624

生活中,有時候我們需要對一些重要的檔案進行加密,python 提供了諸如 hashlib,base64 等便於使用的加密庫。

基礎知識

在 python 中異或操作符為:^,也可以記作 xor。按位異或的意思是:相同值異或為 0,不同值異或為 1。具體來講,有四種可能:0 ^ 0 = 0,0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0。我們還可總結出規律(a 為 0 或 1):0 和 a 異或為 a本身;1 和 a 異或為 a 反。

讓我們想看看一位二進位制數滿足的性質:

b ^ b = 0

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

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

易知,對任意長二進位制數都滿足上述性質。

原理通過了解異或操作的性質,加密原理就非常清晰了。

加密操作:

首先將檔案轉換成二進位制數,再生成與該二進位制數等長的隨機金鑰,將二進位制數與金鑰進行異或操作,得到加密後的二進位制數。

解密操作:

將加密後的二進位制程式與金鑰進行異或操作,就得到原二進位制數,最後將原二進位制數恢復成文字檔案。

生成隨機金鑰:

secrets 庫是 python 3.6 引入的偽隨機數模組,適合生成隨機金鑰。token_bytes 函式接受乙個 int 引數,用於指定隨機位元組串的長度。int.from_bytes 把位元組串轉換為 int,也就是我們需要的二進位制數。

from secrets import token_bytes

def random_key(length):

key = token_bytes(nbytes=length)

key_int = int.from_bytes(key, 'big')

return key_int

加密單元:

encrypt 函式接受乙個 str 物件,返回元組 (int, int)。通過 encode 方法,我們將字串編碼成位元組串。int.from_bytes 函式將位元組串轉換為 int 物件。最後對二進位制物件和隨機金鑰進行異或操作,就得到了加密文字。

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

解密單元:

decrypt 接受兩個 int 物件,分別為加密文字和隨機金鑰。首先對兩者進行異或操作,計算解密出來的 int 物件所佔位元數。decrypted.bit_length 函式得到的是二進位制數的位數,除以 8 可以得到所佔位元大小。為了防止,1 ~ 7 位的二進位制數整除 8 得到 0,所以要加上 7,然後再進行整除 8 的操作。使用 int.to_bytes 函式將解密之後的 int 的物件轉換成 bytes 物件。最後通過 decode 方法,將位元組串轉換成字串。

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()

利用上述函式,我們可以很輕鬆對文字檔案進行加密、解密操作。

>>> raw = '畫圖省識春風面,環珮空歸夜月魂'

>>> encrypted = encrypt(raw)

>>> encrypted

(217447100157746604585...,

9697901906831571319...)

>>> decrypt(*encrypted)

'畫圖省識春風面,環珮空歸夜月魂'

加密文字檔案

path 為待加密檔案的位址,如果不指定金鑰位址,則在該目錄下新建目錄和檔案。

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)

解密檔案

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)

執行完加密、解密檔案操作,得到的解密檔案與原檔案相同,示意圖如下:

-完-

加密解密 異或方式

異或機密和解密工具類 package utils classname securityutil description todo 加密和解密 author wangyl date 2020年8月27日 下午2 27 57 public class securityutil char chs inpu...

PHP使用異或加密解密檔案

原理 將檔案的每乙個位元組與金鑰的單位做異或處理 檔案加密解密方法 param string input 原始檔 param string ouput 加密檔案 param string key 金鑰 function file crypt input ouput key if ouput key ...

異或運算實現簡單的字串加密和解密

異或運算 1 1 0 1 0 1 0 1 1 0 0 0 字元 a 的ascii編碼為65 00000000 01000001 取整數7 00000000 00000000 00000000 00000111 xor運算後 00000000 00000000 00000000 01000110 簡單...