生活中,有时候我们需要对一些重要的文件进行加密,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 反。

让我们想看看一位二进制数满足的性质:

  • 一位二进制数与自身的异或值为 0

b ^ b = 0

  • 异或操作满足交换律

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

  • 0 与 a 的异或为 a

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

解密文件

#Python学习群592539176
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)

执行完加密、解密文件操作,得到的解密文件与原文件相同,示意图如下:

以上就是 Python 加密文件的全部内容,还请大家多多转发支持。

用python实现文件加密功能的更多相关文章

  1. python实现文件加密

    前言: 想实现批量文件加密,可惜批量.展时没有思路 0x1 没有加密前的图片 加密后!!! !!!打不开了 0x02: 代码 import hashlib def get_sha1(f): xd=op ...

  2. python实现文件查找功能,excel写入功能

    因为要丛UE文档中过滤关键字来统计解码时间,第一次自己完成了一个自动化统计的小工具,用起来颇有成就感. UE文件的内如如下: 需要丛这份关键字中过滤红色标记的两个关键字,取 一个关键字的最后一位,和取 ...

  3. Python实现文件阅读功能(Python学习笔记)

    #!/usr/bin/python# Filename: filereader.pyimport sys def readfile(filename): '''Print a file to the ...

  4. python实现更换电脑桌面壁纸,锁屏,文件加密方式

    python实现更换壁纸和锁屏代码 #控制windows系统 import win32api,win32con,win32gui # 可以利用python去调用dll动态库的包.嵌入式开发 from ...

  5. python保留指定文件、删除目录其他文件的功能(1)

    由于给客户的发布版本上客户改动了些代码和图片,我们这边给他们更新publish都是增量更新(开发提供更新指定的文件,我们提取出来给客户进行覆盖更新),但有时需要更新的文件较多导致不得不一个一个的进行查 ...

  6. Windows对python文件加密

    最近项目需要对部分python文件加密,调研了部分方法都觉得不可行,最后采用了将python转换成so文件.pyd文件的方法.so文件,为liunx下的动态链接库文件,在windows下为dll文件, ...

  7. python保留指定文件、删除目录其他文件的功能(2)

    在(1)中脚本实现了保留指定文件的功能,但不能删除空目录,在此补上删除空目录的方法 def DeleteEmptyDir(path): for i in range(1,100): for paren ...

  8. Python之文件与目录操作及压缩模块(os、shutil、zipfile、tarfile)

    Python中可以用于对文件和目录进行操作的内置模块包括: 模块/函数名称 功能描述 open()函数 文件读取或写入 os.path模块 文件路径操作 os模块 文件和目录简单操作 zipfile模 ...

  9. 【转】Python之文件与目录操作(os、zipfile、tarfile、shutil)

    [转]Python之文件与目录操作(os.zipfile.tarfile.shutil) Python中可以用于对文件和目录进行操作的内置模块包括: 模块/函数名称 功能描述 open()函数 文件读 ...

随机推荐

  1. Token:服务端身份验证的流行方案

    01- 身份认证 服务端提供资源给客户端,但是某些资源是有条件的.所以服务端要能够识别请求者的身份,然后再判断所请求的资源是否可以给请求者. token是一种身份验证的机制,初始时用户提交账号数据给服 ...

  2. mysql5.6创建账户不能本地登录

    1.通过xshell连接linux,命令登录mysql 2.创建一个新的库(其实创建不创建都可以) 3.创建账号权限 创建账号luffy 密码luffy 针对库luffy所有权限,允许任何人远程登录 ...

  3. openstack入门及应用

    一.OpenStack云计算的介绍 (一)云计算的服务类型 IAAS:基础设施即服务,如:云主机 PAAS:平台即服务,如:docker SAAS:软件即服务,如:购买企业邮箱,CDN 传统IT IA ...

  4. docker部署java应用程序

    https://docs.docker.com/get-started/ 安装docker   1.安装docker  apt install docker 2.配置docker加速器 安装完成后在 ...

  5. AcWing 1020. 潜水员 二维费用背包

    //体积最多是j 全部为0,v>=0 //体积恰好为j f[0][0]=0,f[i]=无穷,v>=0 //体积至少是j f[0][0]=0,f[i]=无穷,体积为负数时于0取大 #incl ...

  6. 手机大厂必备测试技能-GMS 认证

    GMS认证背景 在之前的一篇文章有给各位小伙伴们科普过关于GMS的作用,http://www.lemfix.com/topics/266 "墙"内的小伙伴可能很少会用到这样的服务, ...

  7. MySQL判断数据是否为空

    IFNULL(expr1,expr2)函数,这个函数只能判断是否为空 SELECT CONCAT(first_name,',',last_name,',',job_id,IFNULL(commissi ...

  8. 字节流和字符流的read方法

    字节流和字符流的read方法 public class Test { public void fileOutput() throws Exception { File file = new File( ...

  9. Linux - 查看静态硬件信息

    概述 查看系统的 信息 一些 相对静态 的信息 背景 一直想写, 但是没来得及整理 每次要用的时候, 都慌里慌张的到处找 这次把他记下来 环境 CentOS 7 下面有些方法, 可能是 centos ...

  10. Iris请求方式和数据返回类型

    1. Iris起服务 package main import "github.com/kataras/iris" func main() { //1.创建app结构体对象 app ...