- 引言
- 本书涉及的内容
- 第 1 部分 Python 开发入门
- 第 1 章 Python 入门
- 第 2 章 开发 Web 应用
- 第 3 章 Python 项目的结构与包的创建
- 第 4 章 面向团队开发的工具
- 第 5 章 项目管理与审查
- 第 6 章 用 Mercurial 管理源码
- 第 7 章 完备文档的基础
- 第 8 章 模块分割设计与单元测试
- 第 9 章 Python 封装及其运用
- 第 10 章 用 Jenkins 持续集成
- 第 11 章 环境搭建与部署的自动化
- 第 12 章 应用的性能改善
- 第 13 章 让测试为我们服务
- 第 14 章 轻松使用 Django
- 第 15 章 方便好用的 Python 模块
- 附录 A VirtualBox 的设置
- 附录 B OS(Ubuntu)的设置
15.3 图像处理
Python 的图像处理通常用 Pillow(Python Imaging Library(Fork))来进行。Pillow 由 PIL(Python Imaging Library)的分支工程开发而来。由于 PIL 已经停止开发及维护,所以如今 Pillow 成为了主流。它支持 JPEG、PNG、GIF、BMP 等多种图像格式。本书使用的是 Pillow 的 2.6.1 版本。
Pillow
http://pillow.readthedocs.org/
15.3.1 安装Pillow
Pillow 与多种处理图像数据的程序库存在依赖关系,因此安装时需要多加注意。目前 Pillow 在 PyPI 上提供了面向 Windows 和 OS X 的 wheel 包。在 Windows、OS X 上安装(包括用 pip 命令安装)时不需要进行编译。如果使用的是其他平台,那么由于需要从 sdist 进行 C 扩展的编译,所以必须准备编译器和各种图像处理库。
◉ 有 wheel 可用的平台
如果是 OS X 和 Windows,只需像 LIST 15.18 这样使用 pip install 安装 wheel 包即可。
LIST 15.18 在OS X 上安装Pillow
$ pip install pillow==2.6.1 Downloading/unpacking pillow==2.6.1 Downloading Pillow-2.6.1-cp27-none-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.whl (2.8MB): 2.8MB downloaded Installing collected packages: pillow Successfully installed pillow Cleaning up...
◉ 从源码构建
接下来准备进行 Pillow 编译时所需的库。下面以 Ubuntu 14.04 为例进行学习。
首先,因为需要编译 C 扩展,所以需要一些基本的开发工具。我们先来确认一下 1.1 节中的安装(LIST 15.19)。
LIST 15.19 检查设置以便进行 python 的 C 扩展编译
$ pkg-config python-2.7 --libs --cflags -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -lpython2.7
另外,图像格式和字体等的支持需要用到下述程序库。
支持对象 | 库 |
JPEG | libjpeg-dev |
OpenJPEG | libopenjpeg-dev |
PNG | zlib1g-dev |
TIFF | libtiff5-dev |
webp | libwebp-dev |
字体 | libfreetype6-dev |
色彩管理 | liblcms2-dev |
执行 LIST 15.20 中的命令,统一安装 Pillow 需要的程序包。
LIST 15.20 安装 Pillow 需要的程序包
$ sudo apt-get install libjpeg-dev libopenjpeg-dev zlib1g-dev libtiff5-dev libfreetype6-dev libwebp-dev liblcms2-dev
现在所需工具和库已经齐全,可以用 pip 进行安装了(LIST 15.21)。
LIST 15.21 用 pip 命令安装 Pillow
$ pip install pillow==2.6.1
安装时会显示支持的图像格式等,我们可以借此查看想要的功能是否已经生效。LIST 15.22 是除 TKINTER 以外的所有功能均生效的例子。
LIST 15.22 查看支持的功能
running build_ext -------------------------------------------------------------------- PIL SETUP SUMMARY -------------------------------------------------------------------- version Pillow 2.6.1 platform linux2 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] -------------------------------------------------------------------- *** TKINTER support not available --- JPEG support available --- OPENJPEG (JPEG2000) support available (2.1.3) --- ZLIB (PNG/ZIP) support available --- LIBTIFF support available --- FREETYPE2 support available --- LITTLECMS2 support available --- WEBP support available --- WEBPMUX support available -------------------------------------------------------------------- To check the build, run the selftest.py script.
NOTE
Pillow 2.6.1 无法识别 Ubuntu 14.04 上安装的 libopenjpeg-dev。今后的版本中应该会修复这个问题。
如果应用不涉及 Tkinter 模块的图像,可以不用管 TKINTER 的支持问题。另外,安装 Python 时,如果 Tkinter 模块并未生效,同样无法支持 TKINTER。
15.3.2 图像格式转换
图像文件的格式转换通过在 Image 类的 save 方法的传值参数中指定格式并保存来完成。下面,我们打开当前目录下名为 python.gif 的图像文件,将其转换为 JPEG 格式,并保存在 python_convert.jpg 文件中。具体代码如下。
# coding: utf-8 from PIL import Image def main(): # 打开文件获取Image 对象 image = Image.open('python.gif') # 模式转换为RGB image_rgb = image.convert('RGB') # 图像保存至文件 image_rgb.save('python_convert.jpg', 'jpeg') if __name__ == '__main__': main()
可以看到,程序在读取完文件之后将图像模式转为了 RGB。
在 GIF 以及不足 256 色的 PNG、BMP 等格式中,颜色信息都保存在调色板数据块里。这类文件用 Pillow 打开时分为 P 模式(调色板模式)和 1 模式(单色模式)。另外,JPEG 文件有时还会是 CMYK 模式。当模式不支持 save 方法指定的格式时,程序会报错,所以要先用 convert 方法进行模式转换。
15.3.3 改变图像尺寸
如果想改变图像尺寸,可以使用 Image 类的 thumbnail 方法或 resize 方法。下面,我们打开当前目录下名为 python.jpg 的图像文件,将其长宽缩小一半后保存为 python_thumbnail.jpg,代码如 LIST 15.23 所示。
LIST 15.23 pil_thumbnail.py
# coding: utf-8 from PIL import Image def main(): # 打开文件获取Image 对象 image = Image.open('python.jpg') # 计算图像长宽的一半 half_size = (image.size[0] / 2, image.size[1] / 2) # 图像大小降为一半 image.thumbnail(half_size, Image.ANTIALIAS) # 图像保存至文件 image.save('python_thumbnail.jpg') if __name__ == '__main__': main()
Image 类的对象能够通过 size 属性以元组的形式获取图像的长和宽。
thumbanil 方法的第一个传值参数指定了图像长和宽的元组,第二个传值参数指定了滤镜 Image.ANTIALIAS。滤镜有 NEAREST、BILINER、BICUBIC、ANTIALIAS4 种可供选择,其中使用 ANTIALIAS 修改尺寸后的图像品质最高(损失最小)。
在执行 thumbnail 方法之后,会直接修改对象自身的图像大小。但是,这个方法只能用于长宽比例不变的修改。变更长宽比例时需要使用 resize 方法。下面,我们打开当前目录下名为 python.jpg 的图像文件,将其长度放大为 2 倍后保存为 python_resize.jpg,具体代码如 LIST 15.24 所示。
LIST 15.24 pil_resize.py
# coding: utf-8 from PIL import Image def main(): # 打开文件获取Image 对象 image = Image.open('python.jpg') # 计算图像长度的2 倍 double_size = (image.size[0], image.size[1] * 2) # 图像大小增加至2 倍 image_resized = image.resize(double_size, Image.ANTIALIAS) # 图像保存至文件 image_resized.save('python_resize.jpg') if __name__ == '__main__': main()
与 thumbnail 方法不同,resize 方法的返回值是修改尺寸后的 Image 类的对象。它同 thumbnail 一样,可以指定滤镜。图 15.1 和图 15.2 分别是修改尺寸之前的图像与执行完 LIST 15.24 所示的代码之后的图像。
图 15.1 修改尺寸之前的图像(python.jpg)
图 15.2 修改尺寸之后的图像(python_resize.jpg)
15.3.4 剪裁图像
Image 类的 crop 方法能够以长方形剪裁图像。下面,我们打开当前目录下名为 python.jpg 的图像文件,按照图像的宽度从正中间剪裁一个正方形并保存为 python_crop.jpg。
LIST 15.25 pil_crop.py
# coding: utf-8 from PIL import Image def main(): # 打开文件获取Image 对象 image = Image.open('python.jpg') # 根据短边长度求中央正方形的坐标 if image.size[0] < image.size[1]: # 横边较短时(瘦高的图像) crop_rect = ( 0, (image.size[1] - image.size[0]) / 2, image.size[0], (image.size[1] - image.size[0]) / 2 + image.size[0]) else: # 竖边较短时(矮胖的图像) crop_rect = ( (image.size[0] - image.size[1]) / 2, 0, (image.size[0] - image.size[1]) / 2 + image.size[1], image.size[1]) # 剪裁 image_croped = image.crop(crop_rect) # 图像保存至文件 image_croped.save('python_crop.jpg') if __name__ == '__main__': main()
crop 方法的传值参数是包含 4 个值的元组(Tuple),这 4 个值代表长方形剪裁区域的左上角坐标和右下角坐标。crop 的返回值为存有剪裁后图像的 Image 类对象。执行 LIST 15.25 中的代码后会得到如图 15.3 所示的结果。
图 15.3 剪裁后的图像(python_crop.jpg)
15.3.5 对图像进行滤镜处理
进行滤镜处理必须获取像素值。像素值可以用 Image 类的 getdata 方法或 getpixel 方法来获取。获取的像素值为包含 R(红)、G(绿)、B(蓝)3 个值的元组,3 个值的范围均为 0 ~ 255。下面,我们打开当前目录下名为 python.jpg 的图像文件,将所有像素反色并保存为 python_filter.jpg。
LIST 15.26 pil_filter.py
# coding: utf-8 from PIL import Image def main(): # 打开文件获取Image 对象 image = Image.open('python.jpg') buffer = [] # 循环逐一获取图像的像素 for pixel in image.getdata(): # 将像素反色并存入缓冲区 buffer.append(( 255 - pixel[0], 255 - pixel[1], 255 - pixel[2])) # 用缓冲区内的像素覆盖原有数据 image.putdata(buffer) # 图像保存至文件 image.save('python_filter.jpg') if __name__ == '__main__': main()
getdata 方法能够返回一个迭代器,用于逐一访问图像的每一组像素值。在上例中,我们逐一取出了每个像素的像素值并进行反色(255 减去色值)。等所有像素值处理完毕之后,用 putdata 方法替换了 Image 类的对象的像素。LIST 15.26 的执行结果如图 15.4。
图 15.4 反色后的图像(python_filter.jpg)
如果要获取指定坐标的像素值,可以用 Image 类的 getpixel 方法。下面,我们打开当前目录下名为 python.jpg 的图像文件,将右上角的像素反色并保存为 python_pixel.jpg,具体代码如 LIST 15.27 所示。
LIST 15.27 pil_pixel.py
# coding: utf-8 from PIL import Image def main(): # 打开文件获取Image 对象 image = Image.open('python.jpg') # 右上角的位置 point = (image.size[0] - 1, 0) # 获取像素值 pixel = image.getpixel(point) # 改写为反色的像素值 image.putpixel(point, ( 255 - pixel[0], 255 - pixel[1], 255 - pixel[2])) # 图像保存至文件 image.save('python_pixel.jpg') if __name__ == '__main__': main()
getpixel 方法的传值参数为含有横纵坐标(起点为 0)两个值的元组。改写指定位置像素值时使用了 putpixel 方法。这些方法的方便之处在于能够指定坐标,但是速度太慢,因此一旦需要大量使用,它们的效率并不见得比 getdata、putdata 等方法更高。
15.4 数据加密
在数据传输过程中,为防止数据被第三方获取或篡改,需要对数据进行加密。这里我们学习一下如何通过 PyCrypto 进行通用加密系统和公钥加密系统的加密及解密。
PyCrypto
https://pypi.python.org/pypi/pycrypto
15.4.1 安装 PyCrypto
如 LIST 15.28 所示,PyCrypto 的安装可以通过 pip 命令进行。由于它包含 C 语言编写的模块,所以安装时与 Pillow 一样需要 gcc 等编译器。各位可以事先用 apt 安装 python-dev 包和 build-essential 包。本书使用的是 PyCrypto 的 2.6.1 版本。
LIST 15.28 用 pip 命令安装 PyCrypto
$ pip install pycrypto==2.6.1
15.4.2 通用加密系统的加密及解密
通用加密系统在加密和解密时使用同一套密钥。AES、DES 等都属于通用加密算法。AES 的密码长度和块长都高于 DES,因此安全性较高。本书使用的就是 AES。
NOTE
DES(Data Encryption Standard)是1977 年被美国标准化的加密系统。
AES(Advanced Encryption Standard)是2011 年被美国标准化的加密系统。
以 AES 加密、解密时需要用到 PyCrypto 的 Crypto.Cipher.AES 类。下面我们用 PyCrypto 实现 AES 加密及解密,并将结果输出到屏幕上(LIST 15.29)。
LIST 15.29 aes_encrypt.py
# coding: utf-8 from Crypto.Cipher import AES KEY = 'testtesttesttest' # 加密和解密时使用的通用密钥 DATA = '0123456789123456' # 数据长度为16 的倍数 def main(): aes = AES.new(KEY) # 生成AES 类的实例 encrypt_data = aes.encrypt(DATA) # 加密 print repr(encrypt_data) # 输出至屏幕 decrypt_data = aes.decrypt(encrypt_data) # 解密 print repr(decrypt_data) # 输出至屏幕 if __name__ == '__main__': main()
给 AES.new 函数指定用作密钥的字符串,生成 AES 对象。密钥可以是长度为 16、24、32 字符的任意字符串。数据通过 AES 对象的 encrypt 方法加密,通过 decrypt 方法解密。上述代码段的执行结果如 LIST 15.30 所示。
LIST 15.30 执行结果
$ python aes.py '\xf7\xf1\x0ccS\xef\x02\xe10\xf2\xe1\xd2\x80{\xcf\xfa' '0123456789123456'
执行结果的第一条输出是加密状态的数据,第二条是将加密的二进制串解密后还原的数据。
15.4.3 公钥加密系统(RSA)的加密与解密
公钥加密系统在加密和解密时分别使用不同的密钥。RSA 等就是公钥加密算法。
NOTE
RSA 是 Ron Rivest、Adi Shamir、Len Adleman 于 1977 年发明的加密算法。
◉ RSA 私钥和公钥的生成
在公钥加密系统中,加密使用公钥(Public key),解密使用私钥(Private key)。这两种密钥都需要通过算法生成。公钥和私钥的密钥对可以通过 ssh-keygen 命令或 openssl 命令来创建,不过我们这里要学习的是用 PyCrypto 生成密钥的方法。下面,我们用 PyCrypto 生成 RSA 的密钥对,以 PEM 格式(RFC1421)输出到屏幕上,具体代码如下。
LIST 15.31 rsa_generate_keypair.py
# coding: utf-8 from Crypto.PublicKey import RSA from Crypto import Random INPUT_SIZE = 1024 def main(): random_func = Random.new().read # 产生随机数的函数 key_pair = RSA.generate(INPUT_SIZE, random_func) # 生成密钥对 private_pem = key_pair.exportKey() # 获取PEM 格式的私钥 public_pem = key_pair.publickey().exportKey() # 获取PEM 格式的公钥 print private_pem # 输出至屏幕 print public_pem # 输出至屏幕 if __name__ == '__main__': main()
LIST 15.31 用 RSA.generate 函数生成了 RSA 密钥对的对象,用 exportKey 方法获取了用作私钥的 PEM 格式的字符串。公钥则是先通过 publickey 方法获取对象,然后再用 exportKey 方法获取的。上述代码的执行结果如 LIST 15.32 所示。
LIST 15.32 执行结果
$ python rsa_generate_keypair.py -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDMYS234o1C1Z2fbeZazcUnEfspBcs06hSmvDji+Jm5Gk6tvIHl IFFu1aCD8kBbjf2ivzmG8Dgtcn6jnLjXe3EB0H1vh70TUsvi0ZjxZsmbv6fJmJrQ zJvW1Wi3wnoBeVYQk6ha8rbfY35wErxxdTWeWm1nSBwaFfnRFYnrkqVGlQIDAQAB AoGBAKJZ39Ne6A/bWOa4inA/XQl4QyeHLrDN8bGxew7xpEtiFnX0dMrqLUX59RRb b7xKwtxxQuVqFXYkqWyWpk6mBFGcRH1yH888Cgu+mSbsKvMAGOW/oTl7XLV8hc4T m0iT/gEUsCHFcE6mstkUIEMlZCWmnuoijprDbehh1OSEZPQBAkEA1IFgXqMGIC/x CYwrizFgJVAa/o4IF183CocfqPaYlotKCeNovnPXeSCmAX1d0GhCHKBIQmkmL7YU TZ1DxiWL1QJBAPY2CWyA26GKGu1WzURJa7guizaqGJpghF30U5VdvdKmetYU2gXA rhHQ9LxdjG09L9BWSxg5Y1Zl02b8f2Qf78ECQQCNr3VBpBCBhXWAmCSwOcuRFUfq UWizrJhWPKGvVjuGpHhI/4bm9PXFnS8R7zSNr/XkgDmtjc4YIZ6H4UM+6enBAkBi yC9jvxdfan9/NdJJUYPMc7AbEIeqeIri/0IBrYiZWX3zIo6OvE2ajFGEuau7sE7c saKTZ4L5iQUWTrv1ufKBAkEAis4KsI4Inxz01ZPRcmPlUVKULvVqyquqsfKP+NFG PTurYiXOc2kXPbBNxyhTDQ6Dw3OB0GhARHSGiuhQQicA2w== -----END RSA PRIVATE KEY----- -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYS234o1C1Z2fbeZazcUnEfsp Bcs06hSmvDji+Jm5Gk6tvIHlIFFu1aCD8kBbjf2ivzmG8Dgtcn6jnLjXe3EB0H1v h70TUsvi0ZjxZsmbv6fJmJrQzJvW1Wi3wnoBeVYQk6ha8rbfY35wErxxdTWeWm1n SBwaFfnRFYnrkqVGlQIDAQAB -----END PUBLIC KEY-----
在输出的字符串中,从 -----BEGIN RSA PRIVATE KEY----- 到 -----END RSA PRIVATE KEY----- 的部分为私钥,从 -----BEGIN PUBLIC KEY----- 到 -----END PUBLIC KEY----- 的部分为公钥。加密解密时就是使用这一对密钥。
◉ 用公钥加密
加密需要使用公钥。PyCrypto 可以使用我们输入的 PEM 格式的公钥字符串。下面,我们将字符串 Hello, world! 加密并输出到屏幕上(LIST 15.33)。
LIST 15.33 rsa_encrypt.py
# coding: utf-8 from Crypto.PublicKey import RSA from Crypto import Random DATA = 'Hello, world!' PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYS234o1C1Z2fbeZazcUnEfsp Bcs06hSmvDji+Jm5Gk6tvIHlIFFu1aCD8kBbjf2ivzmG8Dgtcn6jnLjXe3EB0H1v h70TUsvi0ZjxZsmbv6fJmJrQzJvW1Wi3wnoBeVYQk6ha8rbfY35wErxxdTWeWm1n SBwaFfnRFYnrkqVGlQIDAQAB -----END PUBLIC KEY-----""" def main(): random_func = Random.new().read # 产生随机数的函数 public_key = RSA.importKey(PUBLIC_KEY_PEM) # 输入PEM 格式的公钥 encrypted = public_key.encrypt(DATA, random_func) # 加密数据 print encrypted # 输出至屏幕 if __name__ == '__main__': main()
这段代码用 RSA.importKey 函数输入公钥并获取了 RSA 对象,然后用 encrypt 方法进行加密。encrypt 方法的传值参数处指定了需要加密的数据以及产生随机数的函数。上述代码的执行结果如 LIST 15.34 所示。
LIST 15.34 执行结果
$ python rsa_encrypt.py ('\x05 a\\\xb9U\x88/El\x1a\x02\xe6\xb4\xede\xf2\xe6\xe3\xa6&~\x9e\x180[K%i\x02k\xdd\xd5%\xfd\x1a\xc6\xd7\xc4\xa8\xcf\x86\x07\xdck\x7f\xb4\xb5_,I\x80\xe9\x83\x00*q\xce\xacA\x9a\xe3$]\xe5*\x9e\x91F\xd2\xe3P\xb8+\xa6\xc1R\xde\xf2G\xf1\x185\xcd\x8f\x82\x1a\xa4c\xf5\x9c\xd8\xe0\xd1g \xfdw\xa0\xe6\xca\xf7\x9f\xde\xbf(\xa2\xd5\xdb\xd5}\xe5\xaf\x99\xf9\x90\x1cx\n\xe8\xda\x14\x9cJ\xd7\xe4\x96S',)
◉ 用私钥解密
解密需要使用私钥。与加密时一样,这里也要输入 PEM 格式的字符串。下面,我们把前面加密的数据解密并显示在屏幕上,代码如 LIST 15.35 所示。
LIST 15.35 rsa_decrypt.py
# coding: utf-8 from Crypto.PublicKey import RSA DATA = ('\x05 a\\\xb9U\x88/El\x1a\x02\xe6\xb4\xede\xf2\xe6\xe3\xa6&~\x9e\x180[K%i\ x02k\xdd\xd5%\xfd\x1a\xc6\xd7\xc4\xa8\xcf\x86\x07\xdck\x7f\xb4\xb5_,I\x80\xe9\x83\x00*q\xce\xacA\x9a\xe3$]\xe5*\x9e\x91F\xd2\xe3P\xb8+\xa6\xc1R\xde\xf2G\xf1\x185\xcd\x8f\x82\x1a\xa4c\xf5\x9c\xd8\xe0\xd1g \xfdw\xa0\xe6\xca\xf7\x9f\xdexbf(\xa2\xd5\xdb\xd5}\xe5\xaf\x99\xf9\x90\x1cx\n\xe8\xda\x14\x9cJ\xd7\xe4\x96S',) PRIVATE_KEY_PEM = """-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDMYS234o1C1Z2fbeZazcUnEfspBcs06hSmvDji+Jm5Gk6tvIHl IFFu1aCD8kBbjf2ivzmG8Dgtcn6jnLjXe3EB0H1vh70TUsvi0ZjxZsmbv6fJmJrQ zJvW1Wi3wnoBeVYQk6ha8rbfY35wErxxdTWeWm1nSBwaFfnRFYnrkqVGlQIDAQAB AoGBAKJZ39Ne6A/bWOa4inA/XQl4QyeHLrDN8bGxew7xpEtiFnX0dMrqLUX59RRb b7xKwtxxQuVqFXYkqWyWpk6mBFGcRH1yH888Cgu+mSbsKvMAGOW/oTl7XLV8hc4T m0iT/gEUsCHFcE6mstkUIEMlZCWmnuoijprDbehh1OSEZPQBAkEA1IFgXqMGIC/x CYwrizFgJVAa/o4IF183CocfqPaYlotKCeNovnPXeSCmAX1d0GhCHKBIQmkmL7YU TZ1DxiWL1QJBAPY2CWyA26GKGu1WzURJa7guizaqGJpghF30U5VdvdKmetYU2gXA rhHQ9LxdjG09L9BWSxg5Y1Zl02b8f2Qf78ECQQCNr3VBpBCBhXWAmCSwOcuRFUfq UWizrJhWPKGvVjuGpHhI/4bm9PXFnS8R7zSNr/XkgDmtjc4YIZ6H4UM+6enBAkBi yC9jvxdfan9/NdJJUYPMc7AbEIeqeIri/0IBrYiZWX3zIo6OvE2ajFGEuau7sE7c saKTZ4L5iQUWTrv1ufKBAkEAis4KsI4Inxz01ZPRcmPlUVKULvVqyquqsfKP+NFG PTurYiXOc2kXPbBNxyhTDQ6Dw3OB0GhARHSGiuhQQicA2w== -----END RSA PRIVATE KEY-----""" def main(): # 输入PEM 格式的私钥 private_key = RSA.importKey(PRIVATE_KEY_PEM) # 解密数据 decrypted = private_key.decrypt(DATA) # 输出至屏幕 print decrypted if __name__ == '__main__': main()
与加密时一样,解密也是通过 RSA.importKey 函数输入私钥并获取 RSA 对象。接下来,我们在 decrypt 方法的传值参数中指定已加密的数据进行解密。上述代码的执行结果如 LIST 15.36 所示。
LIST 15.36 执行结果
$ python rsa_decrypt.py Hello, world!
NOTE
为了便于理解,上述例子都是直接在代码中描述公钥和私钥。实际使用时可以从密钥文件中读取密钥数据,从而提高效率。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论