1、第一章 Python基础第一章 Python基础1.1 Python简简介介1.2 配置环配置环境境1.3 Python基础语法基础语法1.4 Python编码编码1.5 函数函数1.6 文件操文件操作作第一章 Python基础1.7 异常处理异常处理try.except.finally1.8 模模块块1.9 面向对面向对象象1.10 正则表达正则表达式式习习题题第一章 Python基础1.1 Python简介简介Python是一种简单易学却又功能十分强大的脚本语言。近年来随着信息安全、人工智能和机器学习的快速发展,学习和使用该语言的用户不断增加。Python是一种解释型语言,其运行速度相对较
2、慢,但是它拥有极高的开发效率和极其强大的内置与外置第三方库,利用Python可以在短时间内开发出满足要求的程序,因此Python在程序开发阶段节省的时间足以弥补其解释型语言运行速度低的缺陷。另外,Python开发的程序通常都以源码形式发布,用户可以根据自己的需求修改代码,扩展性很强。第一章 Python基础1.2 配配 置置 环环 境境1.2.1 Kali安装安装Kali目前的最新版本是2.0,其官方下载网址为https:/www.kali.org/downloads/。建议将Kali安装在虚拟机上,此时只需要在官方网站下载相应的虚拟机镜像文件。目前常用的Kali安装版本如图1-1所示,读者自
3、行选择相应版本下载,然后在VM(虚拟机软件)中导入就可以使用了。登录时使用Kali系统初始的用户名“root”和密码“toor”。第一章 Python基础图1-1 常用的Kali安装版本第一章 Python基础下载Kali后将其解压,并在安装完VM的情况下点击目录下后缀名为vmx的文件,即可运行Kali系统。打开虚拟机,出现图1-2所示的弹窗,点击“我已移动该虚拟机(M)”,即可继续开启虚拟机。第一章 Python基础图1-2 打开虚拟机第一章 Python基础打开虚拟机后,以初始的用户名root、密码toor登录进入Kali系统。如果需要对Kali进行更新以获得最新版本的软件及各种组件,可以
4、使用apt-get命令对系统和软件包进行管理,参见图1-3。第一章 Python基础图1-3 更新Kali系统中的软件第一章 Python基础注注:Kali系统中软件包安装和管理命令apt-get的用法如下:apt-get install package:安装包。apt-get remove package:删除包。apt-get update:更新源。apt-get upgrade:更新已安装的包。apt-get dist-upgrade:升级系统。第一章 Python基础同时,为便于Python中各种第三方库的管理,建议安装pip工具。其操作步骤如下:(1)下载pip安装包:wget ht
5、tps:/bootstrap.pypa.io/get-pip.py-no-check-certificate。(2)以root用户运行命令python get-pip.py,即可完成安装。(3)如果执行pip命令后出现文件或者目录不存在的问题,可以通过建立符号链接来解决。第一章 Python基础第一章 Python基础1.2.2 WingIDE安装安装对于初学者,也可以选择付费软件WingIDE作为开发环境。WingIDE本身使用Python语言开发且功能丰富、易于编程。在Kali中安装WingIDE,首先需要下载其最新的deb安装包(下载网址为http:/ wingide6_6.0.6-1_
6、amd64.deb即可完成安装,如图1-4所示。第一章 Python基础图1-4 安装WingIDE第一章 Python基础WingIDE安装完成后,可以在虚拟机的“Applications”“Usual applications”“Programming”中找到安装好的WingIDE,如图1-5所示。第一章 Python基础图1-5 WingIDE位置第一章 Python基础在Kali中经常会出现WingIDE使用一段时间后在界面上方导航栏中找不到的情况。为了防止这种情况的出现,可以在其安装完成之后将启动快捷方式备份一份在桌面上。在“Files”“Other Locations”“Compu
7、ter”中搜索“wingide”,将搜索结果中的“Wing Pro 6.0”置于桌面以备后用,如图1-6所示。第一章 Python基础图1-6 启动快捷方式第一章 Python基础1.3 Python基础语法基础语法1.3.1 数据类型与变量数据类型与变量在计算机中,不同的数据需要用不同的数据类型来表示。Python支持动态数据类型,程序员不需要提前声明数据类型,解释器会自动识别变量的数据类型。在Python中能够直接处理的数据类型包括整数、浮点数、字符串和布尔值,除此之外还有一些复杂的数据类型,比如列表、数组等。注注:本书演示代码采用Python 2.7编写。第一章 Python基础第一章
8、Python基础程序中的变量都由一个名字来表示。变量名必须是大小写英文、数字和下划线的组合,且不能以数字开头。变量可以是任意的数据类型,它对应的数据存储在内存中,而内存中又可以存储不同类型的值。在下面的代码中,可通过str()函数将整数转换成字符串,然后把两个字符串连接成一个字符串。第一章 Python基础第一章 Python基础1.3.2 字符串字符串Python中的字符串是以单引号、双引号“或者三引号(、”“”)括起来的任意文本,如:hello world、“code”等。单引号和双引号本质上是等价的,单、双引号都支持的好处在于字符串中一旦出现单引号或者双引号时无需用转义字符,而是用另一种
9、引号括起来即可。单引号定义字符串时,会认为字符串里面的双引号“”是普通字符,从而不需要转义;反之用双引号定义字符串时,就会认为字符串里面的单引号是普通字符无需转义。print hello第一章 Python基础第一章 Python基础Python的字符串模块提供了强大的字符串处理能力。下面通过举例来介绍一些常用的字符串处理功能:第一章 Python基础第一章 Python基础1.3.3 列表列表Python语言不像C语言,并没有专用的数组类型,与其相似的概念有以下几个。(1)list:普通的列表,初始化后可以通过特定方法动态增加元素。定义方式:arr=元素(2)Tuple:元组,固定的数组,一
10、旦定义后,其元素是不能修改的。定义方式:arr=(元素)第一章 Python基础第一章 Python基础(3)Dictionary:字典类型,即Hash数组,采用键-值对的形式。定义方式:arr=元素key:values列表(list)是Python内置的一种数据类型,可以用来存储一组不同类型的数据。列表通过使用方括号括起来逗号隔开的不同的数据项即可,核心概念如图1-7所示。第一章 Python基础图1-7 Python中的list数组第一章 Python基础与字符串的索引一样,列表索引从0开始。列表可以通过下标索引或者方括号进行截取、切片、组合等,如:第一章 Python基础Python数组
11、实际上是一个链表,因此定义后不能像PHP之类的语言一样,直接在后面追加元素,而是需要用操作链表的方法操作。常用的方法如表1-1所示。第一章 Python基础第一章 Python基础1.3.4 元组元组元组与列表类似,最大的不同之处在于它不允许修改元组内的元素,如下所示:第一章 Python基础1.3.5 字典字典除了列表外,字典也是Python的一种内置数据类型,用 来表示,其元素为键-值形式,通过键来找其对应的值,字典中没有索引。字典的有关语法点如图1-8所示。第一章 Python基础图1-8 Python中的字典第一章 Python基础可通过以下面代码来学习字典的用法:第一章 Python
12、基础1.3.6 控制语句控制语句和其他计算机语言一样,Python语言的控制语句主要有分支语句和循环语句两种。1.分支语句分支语句Python中条件选择语句的关键字为if、elif和else,其基本形式如下:第一章 Python基础第一章 Python基础例如,if基本用法如下:第一章 Python基础如果判断需要多个条件同时判断时,可以使用or(或)表示两个条件有一个成立时判断条件成功;使用 and(与)时,表示只有两个条件同时成立的情况下,判断条件才成功。注:注:Python不允许在if语句的条件中赋值,所以if 1=2会报错。至于区别,在编程语言中=表示相等;=用于赋值。第一章 Pyth
13、on基础2.循环语句循环语句for循环的语法如下:第一章 Python基础例如,以下代码可计算数组所有元素的和:第一章 Python基础和循环语句经常配合使用的有一个range()内置函数,它可以生成某个范围内的数字列表。比如,range(1,5)就会生成1,2,3,4这样一个列表,而range(5)会生成0,1,2,3,4这样一个列表。例如:第一章 Python基础第一章 Python基础for和while循环语句还可以同if.elif.else结合起来实现各种控制,例如以下代码可找出100以内的素数(注意for.else表达的意思):第一章 Python基础第一章 Python基础3.fo
14、r.if.构建构建ListPython中,for.if.语句可简洁地构建List。从for给定的List中选择出满足if条件的元素组成新的List,其中if是可以省略的。下面举几个简单的例子进行说明。第一章 Python基础第一章 Python基础第一章 Python基础1.4 Python编码编码1.4.1 Python字符编码与解码字符编码与解码通常Python程序需要处理多种字符,如英文字符、中文字符等,例如以下代码:print 你好第一章 Python基础如果在终端直接运行Python code.py,那么程序会报错。这是因为Python中默认的编码是ASCII码,ASCII只支持25
15、6个字符,不支持中文。在Python编码中,为了支持其他字符,必须在源文件的第一行显式指定编码的格式:#-*-coding:utf-8-*-或者#coding=utf-8 注注:#coding=utf-8的“=”号两边不要有空格。第一章 Python基础在Python中,str和unicode这两种字符串类型之间的转换,是由decode函数和encode函数来完成的,如图1-9所示。图1-9 编码与解码第一章 Python基础另外,Python中可用的字符编码有很多,并且还有各种别名,不区分英文大小写,比如UTF-8可以写成u8或者utf8,详细信息可以参考网址:http:/docs.pyth
16、on.org/library/codecs.html#standard-encodings。第一章 Python基础第一章 Python基础如果一个字符串已经是unicode了,再进行解码则将出错,因此通常要对其编码方式是否为unicode进行判断,如下所示:第一章 Python基础1.4.2 数据编码数据编码在使用Python处理密码学问题时,经常需要将一段文本转化为二进制或者十六进制进行一些位操作。Python自带的binascii模块可以很好地满足上述需求。第一章 Python基础第一章 Python基础binascii模块除了上述ASCII编码和十六进制编码以外,还可以实现base64
17、、crc32等编码功能。例如,Base64对应的函数分别是:注注(https:/zh.wikipedia.org/wiki/Base64):第一章 Python基础base64是一种基于64个可打印字符来表示二进制数据的表示方法。base64中的可打印字符包括字母AZ、az,数字09,+、等共64个字符。每个字符可以表示6个比特信息,也就是每6个比特为一个单元,分别对应某个可打印字符。编码时每3个字节(24个比特)切分为4个base64单元,即3个字节数据需要用4个可打印字符来表示。实际上,Python语言专门有个base64模块实现base64编码和解码,具体例子如下:第一章 Python基
18、础第一章 Python基础1.5 函函 数数1.5.1 函数定义函数定义Python函数定义的基本形式如下:第一章 Python基础其中:(1)def是函数定义的关键词,定义时不用指定返回值的类型。(2)函数参数params可以是零个、一个或者多个。函数参数同样也不用指定参数类型,因为在Python中变量都是弱类型的,Python会自动根据值来维护其类型。(3)return返回语句是可选的,它可以在函数体内任何地方出现,表示函数的调用执行到此结束。如果没有return语句,那么会自动返回NONE;如果有return语句,但是在return后面没有接表达式或者值,那么也是返回NONE。第一章 P
19、ython基础举例:第一章 Python基础1.5.2 函数参数函数参数函数可以有默认参数。例如:第一章 Python基础Python函数中,不可变参数(例如数字、字符串、元组)是通过“值”进行传递的,可变对象(例如列表和字典)是通过“指针”进行传递的。例如:第一章 Python基础Python函数的返回值可以有多个变量,相当于返回的是一个元组,只是圆括号()被省略了。例如:第一章 Python基础Python还支持函数的任意参数。第一种方法是在元组中收集不匹配的任意参数。第二种方法是在字典中收集不匹配的关键字参数。*和*表示能够接受0到任意多个参数,*表示将没有匹配的值都放在同一个元组中,*
20、表示将没有匹配的键和值都放在一个字典中。以下代码给出了Python中4种参数传递的情况:第一章 Python基础第一章 Python基础举例:在渗透测试过程中获得了管理员口令的md5哈希值。众所周知md5是不可逆的,无法解密。唯一的办法就是从以往积累的口令字典中,逐个取出口令然后计算其md5值,再和管理员的md5哈希值进行比较,若两值相同则对应的口令就是管理员的口令。假设管理员的md5值为 21232f297a57a5a743894a0e4a801fc3,则穷举破解代码如下:第一章 Python基础第一章 Python基础通过运行crack函数可以得知管理员密码为admin。上述代码中还使用了
21、md5模块,你可以使用help()、dir()函数来快速了解相关模块的函数。第一章 Python基础第一章 Python基础1.5.3 匿名函数匿名函数lambda函数也叫匿名函数,即该函数没有具体的名称:f=lambda 参数1,参数2:返回的计算值 例如:add=lambda x,y:x+yprint add(1,2)3第一章 Python基础lambda语句中,冒号前是参数,可以有多个,参数之间用逗号隔开;冒号右边是返回值。lambda语句构建的其实是一个函数对象,如下所示:第一章 Python基础匿名函数可以作为表达式出现Python语句的任何地方,例如:第一章 Python基础1.5
22、.4 Python中的模块中的模块1.模块的引入模块的引入在Python中用关键字import来引入某个模块,比如要引用math模块,就可以在文件最开始的地方用import math来引入。在调用math模块中的函数时,必须这样引用:模块名.函数名第一章 Python基础在函数名前必须加上模块名,是为了避免在多个模块中含有相同名称的函数情况下,解释器可以无歧义地确定要调用的函数:第一章 Python基础有时候我们只需要用到模块中的某个函数,那么只需要引入该函数即可,此时可以通过以下语句来实现:from 模块名 import 函数名1,函数名2.如果想一次性引入math中所有的函数或者常量,可以
23、通过from math import*来实现,但通常不建议这么做。第一章 Python基础2.定义自己的模块定义自己的模块在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。比如有这样一个文件test.py,在test.py中定义了add函数:第一章 Python基础3.在引入模块时的默认代码执行在引入模块时的默认代码执行先看一个例子,在文件test.py中的代码如下:第一章 Python基础1.5.5 Python脚本框架脚本框架编写Python代码有一定的框架样式。在Python代码的开始部分(起始行),告诉系统需要使用哪一个解释器,如#!/usr/bin/
24、env python;然后通过def main():声明一个main函数,通过main函数调用其他的函数。main函数相当于程序的主入口,通常在命令行下执行Python代码时,都是从main函数开始执行的。Python判断文件是被执行还是被调用(例如通过import方式),依靠的是_name_变量。所以代码最后2行有一个if判断,其目的就在于此。第一章 Python基础需要注意的是,Python使用缩进来对齐和组织代码的执行,所有没有缩进的代码(非函数定义和类定义),都会在载入时自动执行。这些代码,也可以认为是Python的main函数。第一章 Python基础第一章 Python基础1.6
25、文文 件件 操操 作作在上一节的crack函数中枚举了5个口令用于爆破,由于密码数量较少,因此可以很方便地将其放于列表中来遍历。在实际爆破时,可能要枚举成千上万个密码甚至更多,此时不便将这些密码置于列表中。解决此问题的方法就是密码保存在文件中,通过文件操作获得密码。接下来我们改进上面的crack函数,使其获取磁盘中保存有常见弱口令的password.txt来获得密码。第一章 Python基础第一章 Python基础1.字符编码字符编码要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件:f=open(d:gbk.txt,r,encodin
26、g=gbk)f.read()测试第一章 Python基础遇到有些编码不规范的文件,可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的处理方式是直接忽略:f=open(d:gbk.txt,r,encoding=gbk,errors=ignore)第一章 Python基础2.二进制文件二进制文件前面介绍的默认都是读取文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等,用rb模式打开文件即可,如下所示:f=open(d:test.jp
27、g,rb)f.read()bxffxd8xffxe1x00 x18Exifx00 x00.第一章 Python基础1.7 异常处理异常处理try.except.finally异常处理在任何一门编程语言里都是值得关注的一个话题,良好的异常处理可以让程序更加健壮,清晰的错误信息有助于快速修复问题。从本章第一节到本小节,相信读者已经手敲了不少代码。代码多了难免会遇到错误,比如读者在编辑上一页中的代码时,是不是遇到了下面这种状况:第一章 Python基础以上情况就属于IOError异常,后面的英文解释是告诉我们没有找到所谓的D:password.txt文件或目录,遇到这种情况的读者,肯定是在D盘没有创
28、建password.txt文件的基础上执行了上面的代码。第一章 Python基础1.try.except语法语法通过上面例子可以知道,当程序出现异常时,程序抛出异常并终止。这就导致两个问题,首先是直接抛出异常看上去不是很友好,其次是程序出现异常无法继续执行后续代码。接下来将介绍如何通过异常处理来解决这个问题。还是以crack函数为例,可修改crack函数如下所示:第一章 Python基础第一章 Python基础在上述异常处理代码中:(1)except语句不是必需的,finally语句也不是必需的,但是二者必须要有一个,否则就没有try的意义了。(2)except语句可以有多个,Python会按
29、except语句的顺序依次匹配所指定的异常,如果异常已经处理就不会再进入后面的except语句。(3)except语句可以以元组形式同时指定多个异常,如:第一章 Python基础(4)except语句后面如果不指定异常类型,则默认捕获所有异常,可以通过sys模块获取当前异常。第一章 Python基础(5)raise语句表示需要自主抛出一个异常类型,等同于C#和Java语言中的throw语句,其语法规则如下:第一章 Python基础接下来进一步介绍异常处理,这里给出两个例子进行说明,一个是语句不出现异常,另一个是语句出现异常。首先介绍语句出现异常的例子,如下所示:第一章 Python基础语句不出
30、现异常的例子,其代码的执行如下所示:第一章 Python基础通过比较上面两个例子可以发现,except下面的语句只有出现异常且异常与except后面指定异常类型相同时执行(本例中的Exception用于捕获所有异常),else下面的语句在不存在异常的情况下执行,finally下面的语句在两种情况下均会执行。第一章 Python基础2.配合配合try.except错误控制使用错误控制使用在异常处理语句中,当try代码块没有出现任何的异常时,else语句块会被执行。第一章 Python基础结果如下:123convert 123 to integer successfullycannot conve
31、rt me123 to a integer第一章 Python基础1.8 模模 块块1.8.1 sys模块模块Python内置的sys模块提供了对Python解释器和环境有关信息的访问使用与维护函数。sys.argv是一个列表,用于脚本程序从命令行获取参数信息。下面通过简单代码介绍如何通过命令行把参数传递给Python脚本,如下所示:第一章 Python基础第一章 Python基础1.8.2 os模块模块os的含义为操作系统,也就是说Python内置的os模块提供了与操作系统进行交互的功能,包括系统类型、文件和目录操作、命令执行、进程操作等。下面通过一个ping扫描的例子来了解一下os模块。第
32、一章 Python基础第一章 Python基础第一章 Python基础第一章 Python基础第一章 Python基础1.9 面面 向向 对对 象象Python语言可以通过class关键字创建类,下面通过将crack函数的功能拓展为一个Crack类作为示例,介绍如何在Python中创建类,具体代码如下所示:第一章 Python基础第一章 Python基础第一章 Python基础第一章 Python基础上述Crack类中定义了密码文件路径及破解目标的set和get方法,并实现了用crack方法来实施破解的过程。通过观察可以发现,所涉及的每个方法都要传入“self”参数。该类中定义的第一个“_in
33、it_”方法实现了对类对象的初始化。第一章 Python基础1.10 正则表达式正则表达式1.10.1 正则表达式的通用语法正则表达式的通用语法正则表达式本身也算是一种语言,有自己的语法规则。正则表达式可以包含普通字符和特殊字符。普通字符(比如数字或者字母)可以直接对目标字符串进行匹配;而特殊字符可以表示某一类普通字符,或者是改变其周围的正则表达式的含义。表1-2列举了部分正规表达式中的通用字符匹配规则。第一章 Python基础第一章 Python基础第一章 Python基础在正则表达式中,包含“”的特殊序列的意义如表1-3所示。第一章 Python基础1.10.2 Python的的re模块模
34、块Python的re模块提供各种正则表达式的匹配操作,能够在绝大多数情况下有效地实现对复杂字符串的分析并提取出相关信息。Python的re模块正则表达式定义了一系列函数、常量以及异常;同时,正则表达式被编译成RegexObject实例,其本身可以为不同的操作提供方法。接下来简要介绍这些函数的功能和用法。第一章 Python基础pile(pattern,flags)该函数把正则表达式的模式和标识转化成正则表达式对象,供match()和search()两个函数使用。re模块所定义的flag包括:(1)re.I:忽略大小写。(2)re.L:表示特殊字符集w,W,b,B,s,S依赖于当前环境。(3)r
35、e.M:多行模式。第一章 Python基础(4)re.S:即为.,并且包括换行符在内的任意字符(.不包括换行符)。(5)re.U:表示特殊字符集w,W,b,B,d,D,s,S依赖于Unicode字符属性数据库。(6)re.X:为了增加可读性,忽略空格和#后面的注释。第一章 Python基础例如,以下两种用法的结果相同:用法一:用法二:第一章 Python基础2.re.search(pattern,string,flags)该函数在字符串string中查找匹配正则表达式模式的位置,如果找到一个匹配就返回MatchObject的实例(并不会匹配所有的);如果没有找到匹配的位置,则返回None。对于
36、已编译的正则表达式对象(re.RegexObject)来说,有以下search的方法:search(string,pos,endpos)第一章 Python基础若regex是已编译好的正则表达式对象,则regex.search(string,0,50)等同于regex.search(string:50,0)。具体示例如下:第一章 Python基础3.re.match(pattern,string,flags)该函数用于判断 pattern 是否在字符串开头位置有匹配项。对于 RegexObject,有函数:match(string,pos,endpos)match()函数只在字符串的开始位置尝
37、试匹配正则表达式,也就是只报告从位置0开始的匹配情况;而search()函数是扫描整个字符串来查找匹配的。如果想要搜索整个字符串来寻找匹配,应当用search()。第一章 Python基础4.re.split(pattern,string,maxsplit=0,flags=0)该函数将字符串匹配正则表达式的部分割开并返回一个列表。对于RegexObject有函数:split(string,maxsplit=0)第一章 Python基础第一章 Python基础5.re.findall(pattern,string,flags)该函数在字符串中找到正则表达式所匹配的所有子串,并组成一个列表返回。同
38、样,对于RegexObject有函数:第一章 Python基础6.re.sub(pattern,repl,string,count,flags)该函数在字符串string中找到匹配正则表达式pattern的所有子串,用另一个字符串repl进行替换。如果没有找到匹配pattern的子串,则返回未被修改的string。repl既可以是字符串也可以是一个函数。对于RegexObject有函数:sub(repl,string,count=0)第一章 Python基础此语法的示例有:同样可以用以下方法,并指定count为1(只替换第一个):第一章 Python基础1.10.3 实例分析实例分析在使用邮件
39、进行钓鱼之前,攻击者需要收集大量的邮件地址,这些邮件地址通常都是从爬虫收集而来的,而这个爬虫的核心及识别邮件地址则可以使用正则表达式实现。我们通过以下代码演示邮件识别的过程:第一章 Python基础第一章 Python基础在Python中使用正则表达式需要导入re模块;然后将正则表达式ra-zA-Z0-9+a-zA-Z0-9+.com编译成正则表达式对象regx;再调用其findall方法获得所有匹配的邮件地址。第一章 Python基础习习 题题1.编写口令字典生成程序。要求:口令字由字符串abcd中的字符组成,口令长度为3个字符,例如:aaa、abc、bcd、ddd等。第一章 Python基
40、础第一章 Python基础2.编写凯撒加密和解密程序。(提示:ord()和chr()函数。)3.学习使用Python自带的随机数模块(random),随机产生1万个大写字母,并统计每个字母出现的次数。4.利用random库产生满足正态分布的随机数,然后统计各区间段的个数,并用Python的matplotlib画图库显示统计结果。5.破解残缺的MD5。已知一段缺失部分字符的MD5哈希值为34b3c?6232?c8?8f9b?1370,要求还原出MD5值。(已知线索明文为ASDX?HUTAILIN?MENBO?OCT。)第一章 Python基础6.用列表或者字典以及用列表或者字典以及lambda函数实函数实现现base16,base32,base64函数数组,并随机调用其中某个函数对一段秘密信息flag进行10轮次的连续编码。第一章 Python基础第一章 Python基础7.编写函数实现内存的适当显示。8.编写函数,利用re模块实现IP地址的匹配。
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。