Python密码学编程(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-23 09:25:02

点击下载

作者:[美] Al Sweigart 斯维加特

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Python密码学编程

Python密码学编程试读:

前言

有很多书教初学者如何使用加密法写秘密消息,有一些书教初学者如何破译加密法。据我所知,还没有书教初学者如何编写程序来破译加密法。这本书填补了这个空缺。

本书适合不懂加密、破译或密码学的初学者。本书的加密法(除了最后一章的RSA加密法)都有数百年历史了,现代计算机的计算能力可以破译使用它们加密的信息,现代组织或个人已经不再使用这些加密法了。有鉴于此,你不会因为本书里的内容而惹麻烦。

本书适合从来没有编过程序的初学者。本书使用Python编程语言讲解基本编程概念。Python非常适合初学者学习编程:它是一种简单可读却又强大的编程语言,为专业软件开发者所用。Python软件可以从http://python.org免费下载,可以在Linux,Windows,OS X和树莓派上运行。“黑客”有两种定义。一种“黑客”是指通过学习来理解一个系统,并跳出系统原有的规则限制,有创造性地修改它,使之以新的方式来工作的人。另一种“黑客”也用来指入侵计算机系统,触犯个人隐私并造成伤害的罪犯。本书提到的“黑客”是第一种。黑客很酷,罪犯则只是通过破坏来显摆智商的人。就我个人而言,我的本职是一名软件开发者,和写病毒或网络诈骗相比,这份工作钱多活少。

还有一点要注意的,不要把本书里的任何加密程序用于你的实际文件。它们可以带来乐趣,但并不提供真正的安全。一般来说,你不应该信任你自己创造的加密法。正如传奇密码学家Bruce Schneier说的:“任何人,从最无能的外行到最好的密码学家,都能创建出他自己无法破译的算法。这并非难处。难处在于创建出别人无法破译的算法,即使经过数年分析,证明那点的唯一途径是通过各地最好的密码学家对这个算法进行长达数年的分析。”

如果你对这些程序如何工作有问题,可以随时给我发电子邮件:al@inventwithpython.com。第1章制作纸质加密工具

本章主要内容:● 密码学是什么;● 代码和加密法;● 凯撒加密法;● 加密轮盘;● St. Cyr滑条;● 用纸笔做加密;●“ 双重强度”加密。

我忍不住偷听,可能因为我在窃听。——佚名1.1 密码学是什么

看看以下两段文字:

左边的文字是秘密消息。这段消息已被加密,或者说被变成了秘密代码。任何不知道如何解密(也就是把它变回普通英语消息)的人都无法阅读。本书将会教你如何加密和解密消息。

右边的消息只是随机乱码,没有包含任何有意义的内容。加密你写下来的消息是对其他人保密的一种方式,即使他们得到了加密之后的消息。这看起来和随机乱码完全一样。

密码学是使用秘密代码的科学。密码编译者是使用和研究秘密代码的人。本书会告诉你成为一名密码编译者需要知道什么。

当然,这些秘密消息并不总是保持秘密状态。密码破译者是能破译秘密代码并读取其他人的加密消息的人。密码破译者又称为代码破译者(code breaker)或代码黑客(hacker)。本书也会告诉你成为一名密码破译者需要知道什么。遗憾的是,你在本书里学到的破译方式不会给你带来麻烦(我的意思是,幸亏如此)。

间谍、士兵、黑客、海盗、贵族、商人、暴君、政治激进分子、网购者以及任何要与可信好友分享秘密的人都依赖密码学,以确保他们的秘密还是秘密。1.2 代码与加密法

19世纪初发明的电报允许通过跨越大陆的电线进行即时通信,这比带着一袋信件骑马派送要快很多。然而,电报不能直接发送写在纸上的字母,它只能发送电子脉冲。短脉冲叫“点”,长脉冲叫“线”。图1-1 Samuel Morse 1791年4月27日—1872年4月2日图1-2 Alfred Vail 1807年9月25日—1859年1月18日

为了把这些点和线转成英文字母,需要一个编码(或代码)系统把英语翻译成电子脉冲代码(编码),另一边把电子脉冲翻译成英语(解码)。用于电报(后来也用于无线电)的代码叫摩斯代码(Morse Code),由Samuel Morse(见图1-1)和Alfred Vail(见图1-2)发明。通过一个电报按钮敲打出点和线,电报员可以把英语消息发给世界另一端的某个人,几乎是实时的!(如果你想学习图1-3所示的摩斯代码,请到http://invpy.com/morse。)图1-3 国际摩斯代码,通过点和线表示字符

代码是可以理解的,而且是公开发布的。任何人都应该可以通过查找代码符号的含义解密已被加密的消息。1.3 制作纸质加密轮盘

在学习通过计算机编程进行加密和解密之前,我们先来了解一下如何使用简单的纸质工具手工完成这项任务。把可理解的英语文字(明文)变成隐藏秘密代码的乱码文字(密文)是很容易的。加密法(cipher)是一组转换明文和密文的规则。这些规则通常使用一个密钥。我们会在本书里学到多种不同的加密法。

我们来学一下凯撒加密法。这种加密法曾在两千年前被凯撒大帝用过。好消息是,它学起来很简单很容易。坏消息是,正因为它简单,密码破译者也很容易破译它。但我们可以把它看做一个简单的练习。Wikipedia上有更多关于凯撒加密法的信息:[http://en.wikipedia. org/wiki/Caesar_cipher](http://en.wikipedia. org/wiki/Caesar_cipher)。

要用凯撒加密法把明文转成密文,需要制作一个加密轮盘(又名加密圆盘)。你可以复印本书给出的加密轮盘(见图1-4和图1-5),也可以打印http://invpy.com/cipherwheel上的那个加密轮盘。把这两个圆圈剪下来,然后把它们叠在一起,参考图1-6至图1-8所示的步骤。图1-4 加密轮盘内圈图1-5 加密轮盘外圈不要从本书http://invpy.com/cipherwheel上打印上剪!复印本页或从图1-6 剪下加密轮盘图1-7 剪下来的圆圈图1-8 完成后的加密轮盘

剪下两个圆圈之后,把小的放在大的中间。在两个圆圈中间插一根大头针或曲头钉,这样你就可以在上面旋转了。现在,你拥有使用凯撒加密法加密信息所需的工具了。1.4 虚拟加密轮盘

如果你手头没有剪刀和复印机,你也可以使用在线虚拟加密轮盘(见图1-9)。用浏览器打开http://invpy.com/cipherwheel,使用软件版的加密轮盘。图1-9 在线加密轮盘

要旋转轮盘,用鼠标在上面点击一下,然后移动鼠标,直到你想要的密钥在适当的位置上。再次点击鼠标,就可以停止轮盘的旋转。1.5 如何使用加密轮盘加密

首先,在纸上用英语写下你的消息。在这个例子里,我们将会加密这条消息:“The secret password is Rosebud.”。接着,旋转内圈,直到它的字母匹配外圈的字母。值得注意的是,外圈的字母A下面有一个点。再看看外圈里的这个点对应的内圈里的数字,这个数字就是密钥。

这个密钥就是加密或解密消息的秘密所在。任何读过这本书的人都知道凯撒加密法,就像任何读过关于锁的书的人都知道门锁的工作原理。但是,就像平常的锁和钥匙,除非他们有密钥,否则他们不能解锁(也就是解密)已被加密的消息。在图1-9中,外圈的A在内圈的数字8上,这意味着我们将会使用8这个密钥来加密我们的消息。凯撒加密法使用的密钥范围是0~25。我们的例子将会使用8这个密钥。保管好这个密钥,任何知道这条消息使用8这个密钥加密的人都能读懂密文。

对于我们的消息里的每个字母,我们将会找到它在外圈的位置,然后把它替换成内圈对应的字母。我们的消息的第一个字母是T(“The secret…”里的第一个“T”),于是我们在外圈找到字母T,然后找到内圈对应的字母。这个字母是B,因此,我们总会把我们的秘密消息里的T替换成B(如果我们使用8以外的其他密钥,那么明文里的T将被替换成别的字母)。

我们的消息里的下一个字母是H,它会变成P。字母E会变成M。当我们加密完整条消息时,这条消息会从“The secret password is Rosebud.”变成“Bpm amkzmb xiaaewzl qa Zwamjcl.”(见图1-10)。现在你可以把这条消息发给某人(或者给自己写下来),没人可以读懂它,除非你把密钥(数字8)告诉他们。图1-10 用加密轮盘加密的消息

外圈上的每个字母总是加密成内圈上相同的字母。为了节约时间,在你查找“The secret…”里的第一个T,并看到它会加密成B之后,你可以把这条消息里的每个T都替换成B。这样,一个字母你只需要查找一次。1.6 如何使用加密轮盘解密

要解密一条密文,从内圈向外圈走。假设你从一个朋友那里收到这条密文:“Iwt ctl ephhldgs xh Hldgsuxhw.”。你和其他人都不能解密它,除非你知道密钥(或者除非你是个很聪明的黑客)。但你的朋友决定使用15这个密钥加密自己发给你的每条消息。

把外圈上的字母A(下面有个点的那个)对准内圈上带有数字15的字母(即字母P)。密文里的第一个字母是I,因此,我们在内圈上找I,看看旁边外圈上的字母,是T。密文里的W会解密成字母H。一个接一个地,我们把密文里的每个字母解密成明文:“The new password is Swordfish.”。

如果你使用不正确的密钥,比如16,而不是正确的密钥15,解密的消息是:“Sgd mdv ozrrvnqc hr Rvnqcehrg.”。这个明文根本看不懂。除非使用正确的密钥,否则被解密的消息永远不会是可理解的英语。1.7 另一个加密法工具:St. Cyr滑条

还有一个纸质工具可以用来做加密和解密,这个纸质工具叫做St. Cyr滑条。它很像密钥索引轮盘,但它是直的。

复印本页的St. Cyr滑条图片(或者从http://invpy.com/stcyrslide打印),剪下三条纸带,如图1-11所示。图1-11 复印这些纸带制作St. Cyr滑条

连接两条字母表纸带,把黑框A粘在另一条纸带上的白框Z旁边。割开主滑框两边的裂缝,使连接起来的纸条可以穿过它。最后看起来应该是如图1-12所示。图1-12 完成后的St. Cyr滑条

当黑框A在字母H(数字7)下面时,如果要加密,就在长纸带上找出明文字母的位置,然后把它替换成在它上面的字母。如果要解密,就在上面那行字母里找出密文字母,然后把它替换成下面的长纸带上的字母。

大框两边的裂缝会隐藏其他的字母,这样,对于任何密钥,滑条上的每个字母你只会看到一个。

St. Cyr滑条的好处是更容易找到你要找的字母,因为它们都在同一条直线上,不像加密轮盘那样有时候会倒转过来。

虚拟的可打印的St. Cyr滑条可以在http://invpy.com/stcyrslide找到。1.8 A组练习

你可以在http://invpy.com/hackingpractice1A找到练习。

不要忽略练习!

本书没有足够的篇幅列出所有练习,但它们仍然重要。

仅仅阅读关于黑客技术和编程的资料不会让你成为一名黑客。你需要实践!1.9 不用纸质工具做加密

在使用凯撒加密法做加密和解密时,加密轮盘和St. Cyr滑条都是很好的工具。但我们只用铅笔和纸也可以实现凯撒加密法。

把字母表的字母从A到Z写下来,在每个字母下面写下数字0到25。在A下面写0,B下面写1,如此类推,直到在Z下面写25(字母表里有26个字母,但我们的数字最多只到25,因为我们从0而不是1开始的)。最终看起来像这样:

有了上面这个从字母到数字的代码,我们就可以用数字来表示字母了。这是一个非常强大的概念,因为数学使用数字。现在我们可以在字母上做运算了。

现在,如果要加密,我们找到希望加密的字母下面的数字,然后把密钥数字加上去。这个和就是加密的字母下面的数字。如,我们使用密钥13加密“Hello. How are you?”。首先,我们找到H下面的数字,是7。接着,我们把密钥加上这个数字,7 + 13 = 20。数字20在字母U下面,这意味着字母H加密成字母U。如果要加密字母E,我们把E下面的4加上13,得到17。17上面的字母是R,因此E加密成R。如此类推。

直到我们遇上字母O时这个方法才会出问题。O下面的数字是14,当把14加上13时,我们得到27。但我们的数字列表最多只到25。如果字母的数字和密钥之和超过26,我们应该减去26,27 – 26得到1。数字1上面的字母是B。于是,当使用密钥13时,字母O加密成字母B。一个接一个地,我们可以把“HELLO. HOW ARE YOU?”里的字母加密成“URYYB. UBJ NER LBH?”。

因此,加密一个字母的步骤是:

1.从1到25选一个密钥。保管好这个密钥!

2.找出明文字母的数字。

3.把密钥加到这个明文字母的数字。

4.如果这个数字大于26,则减去26。

5.找出你计算的数字的字母。这就是密文字母。

6.对明文消息里的每个字母重复步骤2~5。

表1-1演示了如何使用密钥13加密“HELLO. HOW ARE YOU?”里的每个字母。每列演示了把左边的明文字母变成右边的密文字母的步骤。表1-1 用纸和铅笔加密“Hello. How are you?”的步骤明文字母明文数字+密钥结果减去26?结果密文字母H7+13= 20= 2020 = UE4+13= 17= 1717 = RL11+13= 24= 2424 = YL11+13= 24= 2424 = YO14+13= 27−26= 11 = BH7+13= 20= 2020 = UO14+13= 27−26= 11 = BW22+13= 35−26= 99 = JA0+13= 13= 1313 = NR17+13= 30−26= 44 = EE4+13= 17= 1717 = RY24+13= 37−26= 1111 = LO14+13= 27−26= 11 = BU20+13= 33−26= 77 = H

如果要解密,你需要理解负数是什么。如果你不知道如何加和减负数,可以参考教程http://invpy.com/neg。

如果要解密,减去这个密钥,而不是加上它。对于密文字母B,这个数字是1。1减去13得到−12。就像加密的“减去26”规则,当解密并且结果小于0时,我们有一条“加上26”的规则。−12 + 26是14,因此,如表1-2所示,密文字母B解密回字母O。表1-2 用纸和铅笔解密密文的步骤密文字母密文数字−密钥结果加上26?结果明文字母−U2013= 7= 77 = H−R1713= 4= 44 = EY24−13= 11= 1111 = L−Y2413= 11= 1111 = L= −B113+26= 1414 = O−12U20−13= 7= 77 = H= B1−13+26= 1414 = O−12−J913= −4+26= 2222 = W−N1313= 0= 00 = AE4−13= −9+26= 1717 = R−R1713= 4= 44 = E−L1113= −2+26= 2424 = Y= B1−13+26= 1414 = O−12H7−13= −6+26= 2020 = U

如你所见,使用凯撒加密法加密是并不真的需要加密轮盘。如果你记住数字和字母,你甚至不必写下字母表以及它们下面的数字。你只需心算就可以写出秘密消息了。1.10 B组练习

你可以在http://invpy.com/hackingpractice1B找到练习。1.11 双重强度加密

你可能在想,使用两个不同密钥加密同一条消息两次会加倍加密的强度。但这对于凯撒加密法(以及大多数其他加密法)来说不是那么一回事。让我们双重加密一条消息看个究竟。

如果我们用密钥3加密“KITTEN”这个词,得到的密文将是“NLWWHQ”。如果我们用密钥4加密“NLWWHQ”这个词,得到的密文将是“RPAALU”。这和用密钥7加密“KITTEN”这个词完全一样。“双重”加密和普通加密是一样的,没有任何强化。

其中的原因是,当我们用密钥3加密时,我们把3加到明文字母的数字。接着,当我们用密钥4加密时,我们把4加到明文字母的数字。但加上3再加上4和直接加上7完全一样。用密钥3和4加密两次和用密钥7加密一次是一样的。

对于大多数加密法而言,多次加密不会增加密文的强度。事实上,如果你用两个加起来等于26的密钥来加密某些明文,你最终得到的密文和原来的明文是一样的!1.12 通过计算机编程进行加密

几个世纪以来,凯撒加密法或者类似的加密法曾被用于加密信息。图1-13是Albert Myer设计的加密圆盘,这个加密圆盘曾在1863年的美国南北战争中使用。图1-13 在美国国家密码博物馆展览的美国南北战争同盟使用的加密圆盘

如果你有一段很长的消息希望加密(如加密一整本书),手工加密需要耗费数日或数周的时间。这正是编程派上用场的地方。计算机可以在一秒之内完成大量文字工作。但是,我们需要学习如何指示(也就是编程)计算机执行我们所做的步骤。

我们要会说一门计算机能懂的语言。幸运的是,学习编程语言不像学习日语或西班牙语等外语那么难。你甚至不需要懂太多数学,除了加、减和乘。你只需下载一个叫Python的免费软件,这个软件我们将在下一章里讲解。图1-13 在美国国家密码博物馆展览的美国南北战争同盟使用的加密圆盘

如果你有一段很长的消息希望加密(如加密一整本书),手工加密需要耗费数日或数周的时间。这正是编程派上用场的地方。计算机可以在一秒之内完成大量文字工作。但是,我们需要学习如何指示(也就是编程)计算机执行我们所做的步骤。

我们要会说一门计算机能懂的语言。幸运的是,学习编程语言不像学习日语或西班牙语等外语那么难。你甚至不需要懂太多数学,除了加、减和乘。你只需下载一个叫Python的免费软件,这个软件我们将在下一章里讲解。第2章Pygame基础知识

本章主要内容:● 下载和安装Python;● 下载Pyperclip模块;● 如何启动IDLE;● 本书采用的格式;● 复制粘贴文本。

开放社会的隐私需要密码学。如果我说了什么,我希望听到的人都是我想让他们听到的。如果我讲话的内容全世界都能知道,那我就没隐私了。——Eric Hughes,《A Cypherpunk’s Manifesto》,1993(http://invpy.com/cypherpunk)

本章内容很像Invent Your Own Computer Games with Python的第1章。如果你已经读过那本书或者已经安装Python,你只需阅读本章2.2节。2.1 下载和安装Python

在开始编程之前,你需要安装Python解析器软件(这里你可能需要找人帮忙)。解析器是一个可以理解你用Python语言写的指令的程序。如果没有解析器,你的计算机不会理解这些指令(从现在起,我们会把“Python解析器”称为“Python”)。

因为我们将会使用Python语言写程序,所以我们需要从Python编程语言的官方网站(http://www.python.org)下载Python。安装过程可能会有所不同,这取决于你的计算机的操作系统是Windows、OS X还是Linux发行版(如Ubuntu)。你可以在http://invpy.com/installing找到安装Python软件的视频。

注意:请确保你安装的是Python 3,而不是Python 2。本书的程序使用Python 3,使用Python 2运行它们将会出错。因为这很重要,所以我画了一个卡通企鹅来提醒你安装Python 3(见图2-1),不要搞错。图2-1 “请确保你安装的是Python 3,而不是Python 2!”紧张的企鹅说道2.1.1 Windows安装步骤

http://www.python.org网页左边有一组链接。点击Download链接进入下载页面,找到Python 3.3.0 Windows Installer(“Windows binary–does not include source”)文件,单击这个链接下载Python for Windows(如果有比Python 3.3.0更新的版本,请下载新版本)。双击你下载的python-3.3.0.msi文件启动Python安装程序(如果没有启动,尝试单击这个文件并选择安装)。一旦安装程序启动,单击“下一步”按钮,接受安装程序里的选项,没有什么需要修改。安装结束时单击“完成”。2.1.2 OS X安装步骤

OS X的安装过程与Windows的安装过程类似。你要从Python网站下载的是.dmg(Mac Installer Disk Image)文件,而不是.msi文件。“Download Python Software”页面上包含“Python 3.3.0 Mac OS X”字眼的就是这个文件的链接了。2.1.3 Ubuntu和Linux安装步骤

如果你的操作系统是Ubuntu,打开终端窗口(单击Application\Accessories\ Terminal),输入sudo apt-get install python 3.3,然后按下Enter键,就可以安装Python了。你需要输入根密码才能安装Python,请让这台计算机的所有者输入这个密码。

你也需要安装IDLE软件。在终端窗口里输入sudo apt-get install idle3。你也需要根密码才能安装IDLE。2.2 下载pyperclip.py

这本书里几乎每个程序都会用到我写的pyperclip.py自定义模块。这个模块提供的函数可以让你的程序把文本复制到剪贴板。Python没有附带这个模块,你可以从http://invpy.com/ pyperclip.py下载它。

这个文件和你写的Python程序文件必须放在相同的文件夹里(文件夹也叫目录)。否则当你尝试运行程序时将会看到如下错误消息:ImportError: No module named pyperclip2.3 启动IDLE

我们将会使用IDLE软件输入并运行程序。IDLE全称是Interactive DeveLopment Environment。Python是解析和运行Python程序的软件,IDLE则是用来输入程序的软件。

如果你的操作系统是Windows XP(见图2-2),你应该单击“开始”按钮,选择Programs\ Python 3.3\IDLE (Python GUI)来运行Python。对于Windows Vista或Windows 7,单击左下角的Windows按钮,输入“IDLE”,然后选择“IDLE (Python GUI)”。

如果你的操作系统是Mac OS X(见图2-2),打开Finder窗口,单击Applications,单击Python 3.3,然后单击IDLE图标就可以打开IDLE了。

如果你的操作系统是Ubuntu或其他的Linux(见图2-2),单击Application\Accessories\ Terminal,然后输入idle3就可以打开IDLE了。你也可以单击屏幕顶部的Applications,选择Programming,然后选择IDLE 3。图2-2 在Windows(上)、OS X(中)和Ubuntu Linux(下)上运行的IDLE

显示的窗口基本上都是空白的,除了下面这种文字:Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit(AMD64)] on win32Type "copyright", "credits" or "license()" for more information.>>>

首次启动IDLE时显示的窗口叫做交互式Shell。Shell是一个让你向计算机输入指令的程序。Python Shell让你输入Python指令,然后把这些指令发送给Python解析器软件运行。我们向这个Shell输入Python指令。由于这个Shell是交互式的,计算机会即时读取并执行我们的指令。2.4 特色程序

本书不同于其他编程书籍,它专注于完整程序的源代码。这本书不是教你编程概念,让你自己搞清楚如何创建你自己的程序,而是向你展示完整程序,并解释它们是如何工作的。

在阅读本书时,你可以自己把本书的代码输入IDLE。你也可以从本书的网站下载源代码文件。打开http://invpy.com/hackingsource,按照指示下载源代码文件。

一般而言,你应该从头到尾阅读。这些编程概念都是建立在前面章节基础之上的。但是,Python是一门可读性很强的语言,读了开头几章之后,你就可以搞清楚这些代码是做什么的了。如果你跳着读,读着读着感到糊涂了,不妨回到前面的章节看看,或者把你的编程问题通过邮件地址al@inventwithpython.com发给我。2.5 行号和空格

当你自己输入源代码时,不要输入每行开头显示的行号。例如,如果你在本书里看到这段代码:1. number = random.randint(1, 20)2. spam = 423. print('Hello world!')

你不需要输入左边的“1.”以及紧跟其后的空格。只要这样输入就行了:number = random.randint(1, 20)spam = 42print('Hello world!')

那些编号只是用来引用本书代码的特定行。它们不是实际程序的一部分。除了这些行号,请确保输入的代码和看到的完全一致,包括字母大小写。在Python里,HELLO、hello和Hello是三个不同的东西。

注意,某些行不是从最左边开始的,而是会缩进4个或8个空格。请确保在每行开始输入正确数量的空格。因为IDLE里的每个字符都是等宽的,数一下上一行或者下一行的字符数就可以知道这行的空格数了。

例如,你可以看到第二行缩进了4个空格,因为上一行对应缩进空格的地方有4个字符(“whil”);第三行再缩进了4个空格(第三行的缩进空格上有“if n”4个字符):while spam < 10: if number == 42: print('Hello')2.6 本书的文本换行

某些代码太长,一行放不下,代码的文字就会换行。当你在文件编辑器里输入这种代码时,把它们全部放在一行,中间没有换行。

你可以通过代码左边的行号来判断是不是新的一行。下面的例子只有两行代码,但是第一行内容太多,所以有自动换行:1. print('This is the first line! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’)2. print('This is the second line!')2.7 在线跟踪程序

跟踪程序就是单步调试代码,每次一行,就像计算机执行它那样。你可以访问http://invpy. com/hackingtraces,查看本书每个程序的跟踪结果。这个跟踪Web页面对每步跟踪提供注解和有帮助的提醒,解释这个程序在做什么,帮助你更好地理解这些程序为什么可以这样工作。2.8 使用在线比较工具检查输入的代码

虽然通过输入这些程序的源代码来学习Python很有帮助,但你可能不小心输入错误导致程序崩溃。输入错误的位置可能无法一眼看出。

你可以复制粘贴你输入的源代码的文本到本书网站的在线比较工具。这个比较工具会显示本书代码和你输入的代码之间的差别。这是找出你的程序的输入错误的一个简单方法。

这个在线比较工具在http://invpy.com/hackingdiff。有一段关于如何使用这个比较工具的视频也可以在本书的网站http://invpy.com/hackingvideos上找到。2.9 复制粘贴文本

复制粘贴文本是一项有用的计算机技能,尤其对于本书而言,因为很多将要加密或解密的文本很长。你可以在本书的网站上找到文本的电子版,然后从你的浏览器复制文本粘贴到IDLE里,而不必手动输入。

要复制粘贴文本,你先在希望复制的文本上拖动鼠标,这会选中文本。接着,你点击编辑\复制菜单项,或者在Windows上按下Ctrl-C(按住Ctrl键,然后按一次C,接着松开Ctrl键)。在Mac上,键盘快捷方式是Command-C(即⌘键)。这会把选中的文本复制到计算机内存,或者说剪贴板。

要粘贴剪贴板上的文本时,把鼠标指针移到你希望插入文本的地方,然后点击编辑\粘贴菜单项,或者Ctrl-V或Command-V。粘贴和手动输入复制到剪贴板的所有字符具有相同的效果。复制粘贴可以为你节约大量输入时间,与输入不同的是,它在产生文本的过程中不会出错。

值得注意的是,每次复制文本到剪贴板,之前在剪贴板上的文本就会消失。

本书网站http://invpy.com/copypaste上有一个关于复制粘贴的教程。2.10 更多信息链接

关于编程和密码学还有很多可以学习的,但你不需要现在就把所有的都学了。有时候,你可能了解这些额外的细节和解释,但如果我把它们都放到这本书里,就会增加很大篇幅。出版这么大的一本书会把大量容易着火的纸聚在一起,使之会变成一个火灾隐患。我在本书里包含了“更多信息”链接,你可以通过它们访问本书的网站。你不需要阅读这些额外的信息来理解本书的任何东西,但这些信息可以帮助你学习。这些链接以http://invpy.com开头(这是“Invent with Python”书籍网站的短网址)。

即使本书不是危险的火灾隐患,也请无论如何不要点燃它。2.11 编程和密码学

编程和密码学是两个独立的技能,但一起学是很有用的,因为计算机做加密比人更快。比如说,以下是用简单替换密码的方式加密莎士比亚的《罗密欧与朱丽叶》之后的全部文本:

如果你尝试手工加密,每天工作12小时,周末休息,需要大约三周时间才能完成加密。或许你还会犯些错误。然后需要另外的三周时间才能解密这段加密的文本。

你的计算机只需不到两秒就能完全加密或解密整部戏剧。

但你需要知道如何进行计算机编程才能加密。这就是本书的目的了。如果你会计算机编程,你也可以破译别人加密并试图保密的密文。学习计算机编程,学习成为一名黑客。

让我们开始吧!第3章交互式Shell

本章主要内容:● 整数和浮点数;● 表达式;● 值;● 运算符;● 计算表达式;● 把值存到变量里;● 重写变量。

在开始编写加密程序之前,我们应该先学一点基本编程概念,这些概念包括值、运算符、表达式和变量。如果你读过Invent Your Own Computer Games with Python或者已经了解Python,你可以直接跳到第5章。

我们先来学习如何使用Python的交互式Shell。你应该在计算机旁边读这本书,这样你就可以输入代码示例,亲自看看它们做什么。3.1 一些简单的数学知识

打开IDLE,你会看到交互式Shell以及>>>(我们称之为提示符)旁边闪烁的光标。这个交互式Shell可以当做计算器来用。在这个Shell里输入2 + 2,然后按下键盘上的Enter键(在某些键盘上是Return键)。如图3-1所示,计算机应该返回数字4。图3-1 在Shell里输入2 + 2

2 + 2本身并不是程序,而只是一条指令(我们现在只是在学基础知识)。+号告诉计算机把数字2加上2。要做减法用−号,要做乘法用星号(*),要做除法用/(见表3-1)。表3-1 Python里的各种数学运算符运算符运算+加法-减法乘法*/除法

以这种方式使用的话,+、-、*和/叫做运算符,因为它们告诉计算机对包围它们的数字执行某种运算。两个2(或者其他数字)叫做值。3.2 整数和浮点数

在编程里,完整的数字(如4、0和99)叫做整数。带有小数或小数点的数字(如3.5、42.1和5.0)是浮点数。在Python里,数字5是一个整数,但如果我们把它写成5.0,那它就是一个浮点数了。3.3 表达式

试着把这些数学问题输入Shell,在每行后面按Enter键:2+2+2+2+28*610-5+62+2

图3-2展示了在你输入上面那些指令之后交互式Shell的样子。

这些数学问题叫做表达式(见图3-3)。计算机可以在数秒之内求解数百万个这样的问题。表达式由值(数字)和连接它们的运算符(数学符号)组成。整数和这些运算符之间可以有任意空格。但请确保总是从行首开始,前面没有空格。图3-2 输入指令后IDLE窗口的样子图3-3 表达式由值(如2)运算符(如+)组成和3.4 运算符顺序

你可能记得数学课上的“运算符顺序”。如乘法的优先级比加法高。Python的*和+运算符也是这样。如果一个表达式同时包含*和+运算符,*运算符会先计算。在交互式Shell里输入以下表达式:>>> 2 + 4 * 3 + 115>>>

因为*运算符会先计算,所以2 + 4 * 3 + 1会得到2 + 12 + 1,然后得到15。而不是先得到6 * 3 + 1,再得到18 + 1,最后得到19。不过,你可以使用圆括号来改变运算符的优先级。在交互式Shell里输入以下表达式:>>> (2 + 4) * (3 + 1)24>>>3.5 计算表达式

当计算机处理表达式10 + 5并得到15这个值时,我们说它计算了这个表达式。计算一个表达式会把这个表达式约简成单个值,就像求解一个数学问题会把这个问题约简成单个数字:答案。

计算一个表达式(换句话说,把它约简)总会得到单个值。

10 + 5和10 + 3 + 2这两个表达式的值一样,因为计算它们都得到15。即使单个值也被看做表达式:计算15这个表达式得到15这个值。

然而,如果你只在交互式Shell里输入5 +,你会得到一个错误消息:>>> 5 +SyntaxError: invalid syntax

出现这个错误是因为5 +不是一个表达式。表达式包含的值由运算符连接,在Python语言里,+运算符期望连接两个值。我们在“5 +”里只给它一个值,这就是为什么会出现错误信息。语法错误意味着计算机不懂你给它的指令,因为你输入有误。这看起来似乎不重要,但很多时候,计算机编程不只是告诉计算机做什么,还要确切地知道如何告诉计算机去做。3.6 错误是可以接受的

犯错是完全可以接受的!你输入有问题的代码会导致错误,但不会弄坏你的计算机。如果你输入的代码导致了错误,Python只会提示有错误,然后再次显示>>>提示符。你可以在交互式Shell里继续输入新代码。

直到你积累了更多编程经验,这些错误消息才会对你有很大帮助。你总是可以通过Google搜索某个错误消息的文字,找到解释这个错误的网页。你也可以到http://invpy.com/errors查看常见的Python错误消息列表以及它们的含义。3.7 A组练习

你可以在http://invpy.com/hackingpractice3A找到练习。3.8 每个值都有一个数据类型“整数”和“浮点数”被称为数据类型。每个值都有一个数据类型。42这个值是一个整数数据类型的值,我们会说42是一个int。7.5这个值是一个浮点数数据类型的值,我们会说7.5是一个float。

我们还会学到其他数据类型(如下一章的字符串),但现在只需记住,任何时候我们提到“值”,那个值都会是某种数据类型。指出这个数据类型通常也很容易,只需看看这个值是怎么打出来就可以了。整数是不带小数点的数字,浮点数是带有小数点的数字。因此,42是一个整数,但42.0是一个浮点数。3.9 通过赋值语句把值存到变量里

程序会经常需要保存计算表达式得到的值,以便后面可以使用。我们可以把值存到变量里。

变量可以看做装有值的盒子。你可以通过=符号(称作赋值运算符)把值存到变量里。比如说,要把15这个值存到一个名为“spam”的变量里,在Shell里输入spam = 15:>>> spam = 15>>>

你可以把这个变量想象成一个盒子,里面装有15这个值(如图3-4所示)。变量名“spam”是盒子上的标签(这样我们就可以把一个变量和另一个变量区分开来),存到里面的值就像这个盒子里面的一张小便签。图3-4 变量就像带有名字的盒子,里面装着值

当你按下Enter键时,你不会看到任何东西,除了一个空行。除非你看到一个错误消息,否则你可以假设这条指令已经成功执行了。下一个>>>提示符会显示,以便你输入下一条指令。

带有=赋值运算符的指令(称作赋值语句)创建spam这个变量,并把15这个值存到里面。和表达式不同,语句是不会算得任何值的指令,它们只执行某个操作。这正是为什么Shell里的下一行上没有显示值的原因。

或许你很难搞清楚哪些是表达式,哪些是语句。你只需记住,如果计算一条Python指令得到单个值,这就是表达式。否则,这是语句。

赋值语句由变量、=运算符和表达式组成(见图3-5)。计算这个表达式得到的值会存到这个变量里(15这个值本身就是一个表达式,计算它会得到15)。图3-5 赋值语句的各个部分

记住,变量保存单个值,而不是表达式。如果我们有spam = 10 + 5这个语句,那么10 + 5这个表达式会先算得15,接着,15这个值会存到spam这个变量里。变量会在你首次通过赋值语句把一个值存到里面时创建出来。>>> spam = 15>>> spam15>>>

有趣的事情来了。现在,如果我们在Shell里输入spam + 5,我们会得到整数20:>>> spam = 15>>> spam + 520>>>

这看起来可能有点奇怪,但当我们记起曾把spam的值设为15,就会发现它是有意义的了。因为我们已把spam这个变量的值设为15,计算spam + 5这个表达式会得到15 + 5这个表达式,然后得到20。计算表达式里的变量名会得到存到那个变量里的值。3.10 重写变量

我们可以通过输入另一个赋值语句改变存到变量里的值。你可以试一下这样做:>>> spam = 15>>> spam + 520>>> spam = 3>>> spam + 58>>>

我们第一次输入spam + 5时,计算这个表达式会得到20,因为我们在spam这个变量里保存了15这个值。但当我们输入spam = 3时,15这个值被3这个值重写了(也就是替换了)。现在,当我们输入spam + 5时,计算这个表达式会得到8,因为计算spam + 5现在会得到3 + 5。spam里的旧值已经没有了。

要知道一个变量的当前值是什么,在Shell里输入这个变量名就可以了。>>> spam = 15>>> spam15

之所以可以这样,是因为变量本身也是一个表达式,计算之后会得到存到这个变量里的值。这就像一个值本身也是一个表达式,计算之后得到它本身:>>> 1515

我们甚至可以用spam这个变量的值来给spam赋一个新值:>>> spam = 15>>> spam = spam + 520>>>

spam = spam + 5这个赋值语句就像是在说:“spam这个变量的新值将是spam的现值加上5。”记住,=符号左边的变量会被赋予右边表达式计算之后得到的值。我们可以多次把spam的值加5:>>> spam = 15>>> spam = spam + 5>>> spam = spam + 5>>> spam = spam + 5>>> spam30>>>3.11 使用多个变量

根据你的需要,你的程序可以有很多个变量。比如说,我们可以给eggs和fizz两个变量赋予不同的值:>>> fizz = 10>>> eggs = 15

现在,如图3-6所示,fizz这个变量里有10,eggs这个变量里有15。图3-6 fizz和eggs两个变量里都存有值

我们尝试给spam这个变量赋一个新值。在Shell里输入spam = fizz + eggs,然后在Shell里输入spam查看spam的新值。在交互式Shell里输入以下代码:>>> fizz = 10>>> eggs = 15>>> spam = fizz + eggs>>> spam25>>>

spam的值现在是25,因为当我们把fizz和eggs加起来时,我们加的是fizz和eggs里保存的值。3.12 变量名

计算机不在乎你怎么命名你的变量,但你应该在乎。如果给变量的命名能够反映它们包含的数据的类型,可以让人更容易理解程序做什么。我们不用name来命名变量,而用abrahamLincoln或monkey,计算机运行程序的结果是一样的(只要你始终使用abrahamLincoln或monkey)。

变量名(以及Python里的其他东西)是区分大小写的。区分大小写意味着相同的变量名不同的大小写会被认为是完全不同的变量。因此,在Python里,spam、SPAM、Spam和sPAM会被认为是4个不同的变量,它们每个都能包含它们自己不同的值。

在程序里使用不同大小写的变量是不好的。如果你把你的名字存到name这个变量里,把你的姓氏存到NAME这个变量里,几周之后重读代码时可能会感到混乱。name表示名字,NAME表示姓氏,还是反过来?

如果你不小心交换了name和NAME两个变量,你的程序仍然会运行(也就是没有任何“语法”错误),但运行结果是错误的。代码里的这种瑕疵叫做缺陷(bug)。很多时候,编程不只是写代码,还要修复缺陷。3.13 驼峰式大小写

如果变量名包含超过一个单词,使用大写字母是有帮助的。如果你把“你吃了什么早餐”以字符串的形式存到一个变量里,则whatIHadForBreakfast这个变量名比whatihadforbreakfast更容易读。这就是驼峰式大小写(camel case),因为大小写的起伏像骆驼的驼峰。这是Python编程惯例(也就是可选的标准做事方式),虽然todaysBreakfast这种简单的写法可能更好。让变量名的第一个单词后的每个单词的首字母大写会使程序更加可读。3.14 B组练习

你可以在http://invpy.com/hackingpractice3B找到练习。3.15 小结

很快。但是,为了破译密码,我们需要再学一些基本编程概念。在开始编写加密程序之前,我们不需要学很多东西,但还有一章编程内容是我们需要讲的。

你在本章里学到在交互式Shell里写Python指令的基础知识。Python需要你精确地告诉它要做什么,因为计算机没有常识,只懂很简单的指令。你了解到Python可以计算表达式(即把表达式约简成单个值),表达式由值(如2或5)和运算符(如+或-)构成。你也了解到可以把值存到变量里,这样你的程序就能记住它们,以便日后使用。

交互式Shell是学习Python指令的好帮手,因为它让你每次输入一条指令然后看结果。在下一章里,我们会创建包含很多指令的程序,这些指令会按顺序执行,而不是每次一条。我们将会探讨更多基本概念,你也将会编写你的第一个程序!第4章字符串和写程序

本章主要内容:● 字符串;● 字符串连接和复制;● 使用IDLE写源代码;● 在IDLE里保存并运行程序;● print()函数;● input()函数;● 注释。

整数和数学的内容暂时到此为止。Python并非只是一个计算器。在本章里,我们将学习如何在变量里保存文本,把文本连接起来,以及在屏幕上显示文本。我们也将创建我们的第一个程序,它会通过“Hello World!”这句话向用户问好,并让用户输入名字。4.1 字符串

在Python里,我们使用的小块文本称为字符串值(或者简单地称为字符串)。我们的所有加密法和破译程序都是通过处理字符串值,把像“One if by land,two if by space”这样的明文转换成“Tqe kg im npqv,jst kg im oapxe.”这样的密文。明文和密文在我们的程序里是用字符串值来表示的,Python代码可以通过多种方式操作这些值。

我们可以把字符串值保存在变量里,就像整数和浮点数值那样。当我们输入字符串时,我们把它们放在两个单引号(')之间,表示字符串的起止。在交互式Shell里输入这行代码:>>> spam = 'hello'>>>

单引号并非字符串值的一部分。Python知道'hello'是一个字符串,spam是一个变量,因为字符串是由单引号包围的,而变量名不是。

如果你在Shell里输入spam,你应该看到spam变量的内容('hello'字符串)。这是因为Python会计算变量,并得到保存在它里面的值:在这里是'hello'这个字符串。>>> spam = 'hello'>>> spam'hello'>>>

字符串里可以放置任何键盘字符(稍后我们将会讨论特殊的“转义字符”)。这些都是字符串的示例:>>> 'hello''hello'>>> 'Hi there!''Hi there!’>>> 'KITTENS''KITTENS'>>> ''''>>> '7 apples, 14 oranges, 3 lemons''7 apples, 14 oranges, 3 lemons'>>> 'Anything not pertaining to elephants is irrelephant.' 'Anything not pertaining to elephants is irrelephant.'>>> 'O*&#wY%*&OcfsdYO*&gfC%YO*&%3yc8r2' 'O*&#wY%*&OcfsdYO*&gfC%YO*&%3yc8r2'</p><p>值得注意的是,''字符串里包含0个字符,也就是单引号之间没有任何东西。这称为空字符串。4.2 使用+运算符的字符串连接</p><p>你可以使用+运算符把两个字符串值加起来,变成一个新的字符串值。这种操作叫做字符串连接。试一下在Shell里输入'Hello' + 'World!':>>> 'Hello' + 'World!''HelloWorld!'>>></p><p>要在“Hello”和“World!”之间放一个空格,可以把一个空格放在'Hello'字符串的末尾、单引号之前,像这样:>>> 'Hello ' + 'World!''Hello World!'>>></p><p>记住,Python会“老实地”连接你让它连接的字符串。如果你希望结果字符串里有一个空格,那么两个原始字符串必须有一个包含这个空格。</p><p>+运算符可以把两个字符串值连接起来得到一个新的字符串值('Hello ' + 'World!'得到'Hello World!'),就像它可以把两个整数值加起来得到一个新的整数值一样(2 + 2得到4)。Python可以根据这些值的数据类型判断+运算符应该做什么。每个值都有一个数据类型,'Hello'这个值的数据类型是字符串,5这个值的数据类型是整数。数据的数据类型告诉我们(以及计算机)这个值是一种什么样的数据。</p><p>+运算符可以用在两个字符串或两个整数的表达式里。如果把+运算符用于一个字符串值和一个整数值将会出错。在交互式Shell里输入以下代码:>>> 'Hello' + 42Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: Can't convert 'int' object to str implicitly>>> 'Hello' + '42''Hello42'>>>4.3 使用*运算符的字符串复制</p><p>你也可以在一个字符串和一个整数之上使用*运算符进行字符串复制(string replication)。这会复制(也就是重复)一个字符串,这个整数值是复制的次数。在交互式Shell里输入以下代码:>>> 'Hello' * 3'HelloHelloHello'>>> spam = 'Abcdef'>>> spam = spam * 3>>> spam'AbcdefAbcdefAbcdef'>>> spam = spam * 2>>> spam'AbcdefAbcdefAbcdefAbcdefAbcdefAbcdef'>>></p><p>*运算符可以用于两个整数值(它会将它们相乘),也能用于一个字符串值和一个整数值(它会复制这个字符串)。但它不能用于两个字符串值,这会出错:

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载