返回介绍

15.3 图像处理

发布于 2024-01-21 17:11:03 字数 16493 浏览 0 评论 0 收藏 0

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文