python笔记 二更
pyc文件是py文件编译后生成的字节码文件(byte code),pyc文件经过python解释器最终会生成机器码运行。
因此pyc文件是可以跨平台部署的,比如Java的.class文件,一般py文件改变后,都会重新生成pyc文件。
1.Python 标识符
标识符由字母、数字、下划线组成。
在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。
Python 中的标识符是区分大小写的。
Python 可以同一行显示多条语句,方法是用分号 ; 分开
2.行和缩进
代码块不使用大括号 {} 来控制类,函数以及其他逻辑判断。
用缩进来写模块。
缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量,这个必须严格执行。
出现IndentationError: unexpected indent 错误, 则可能是tab和空格没对齐的问题",所有 python 对格式要求非常严格。
3.注释类型
在 Python 中,通常包括 3 种类型的注释,分别是单行注释、多行注释和中文编码声明注释。
Python单行注释:使用井号(‘#’)作为单行注释的符号,语法格式为:# 注释内容
Python多行注释:多行注释指的是可以一次性注释程序中多行的内容。
4.变量
注意变量名称不能有特殊符号* 不能以数字开头
关键字不能当做变量名称使用if、input等
内建函数不能使用(内建函数:type()、int()等)
区分大小写
5.while语句
while 语句用于循环执行程序,即循环执行某段程序,以处理需要重复处理的相同任务。
执行语句可以是单个语句或语句块。判断条件可以是任何表达式,任何非零、或非空(null)的值均为true。
当判断条件假 false 时,循环结束。
6.条件语句
条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。
指定任何非0和非空(null)值为true,0 或者 null为false。
Python 编程中 if 语句用于控制程序的执行基本形式为:
if 判断条件:
执行语句……
else:
执行语句……
其中"判断条件"成立时(非零),则执行后面的语句,而执行内容可以多行,以缩进来区分表示同一范围。
else 为可选语句,当需要在条件不成立时执行内容则可以执行相关语句。
if 基本用法 flag = False name = 'luren' if name == 'python': # 判断变量是否为 python flag = True # 条件成立时设置标志为真 print 'welcome boss' # 并输出欢迎信息 else: print name # 条件不成立时输出变量名称
7.while循环语句
用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为:
while 判断条件(condition):
执行语句(statements)……
执行语句可以是单个语句或语句块。判断条件可以是任何表达式,任何非零、或非空(null)的值均为true。
当判断条件假 false 时,循环结束。
条件满足则循环,子语句多可以全部选中再按tab来实现缩进
break:只要执行break(满足break上面的条件)则立即跳出循环
continue:当该语句被执行,会结束当前循环,继续下一次循环,continue下面的语句 不执行(用来取出循环值使用)
8.for循环语句
可以遍历任何序列的项目,如一个列表或者一个字符串。
for循环的语法格式如下:
for iterating_var in sequence:
statements(s)
循环使用else语句,else 中的语句会在循环正常执行完的情况下执行,while … else 也是一样。
9.Break语句
像在C语言中,打破了最小封闭for或while循环。
用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句。
break语句用在while和for循环中
10.continue语句
用于跳出本次循环,区分break跳出整个循环。
continue 语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环。
用在while和for循环中
11.元组
元组与列表类似,不同之处在于元组的元素不能修改。
使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
创建空元组
tup1 = ()
元组中只包含一个元素时,需要在元素后面添加逗号
tup1 = (50,)
元组与字符串类似,下标索引从0开始,可以进行截取,组合
12.字典
整个字典包括在花括号{}中,字典没有索引值,靠键值对来取值(通常先取键,若要取值可以alist[adict])
格式:
{"key":"value"}key是键,value是值
用来解决多账户对应唯一密码
userdict = {"admin1":"admin1","admin2":"admin2"}
13.return语句
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
结果:函数内 : 30
14.变量作用域
一个程序的所有的变量并不是在哪个位置都可以访问的。
访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。两种最基本的变量作用域为
全局变量/局部变量
15.全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。
16.列表LIST
序列是Python中最基本的数据结构。
序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
Python有6个序列的内置类型,最常见的是列表和元组。
序列都可以进行的操作包括索引,切片,加,乘,检查成员。
Python内置确定序列的长度以及确定最大和最小的元素的方法。
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
列表的数据项不需要具有相同的类型。
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。
例:
list1 = ['qdcn', 'upc', 1997, 2000]
list2 = [1, 2, 3, 4 ]
list3 = ["e", "f", "g", "h"]
17.访问列表中的值
使用下标索引来访问列表中的值,同样也可以使用方括号的形式截取字符,
例:
#!/usr/bin/python
list1 = ['qdcn, 'UPC', 1997, 2000]
list2 = [1, 2, 3, 4, 5, 6, 7 ]
print "list1[0]: ", list1[0]
print "list2[1:5]: ", list2[1:5]
以上实例输出结果:
list1[0]: qdcn
list2[1:5]: [2, 3, 4, 5]
18.模块
模块是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块能够有逻辑地组织Python 代码段。
把相关的代码分配到一个模块里能让代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
19.import 语句
模块定义好后,我们可以使用 import 语句来引入模块:
import module1[, module2[,... moduleN]]
当解释器遇到 import 语句,模块在当前的搜索路径就会被导入。
搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 ,需要把命令放在脚本的顶端。
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
20.from…import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:
from fib import fibonacci
这个声明不会把整个 fib 模块导入到当前的命名空间中,它只会将 fib 里的 fibonacci 单个引入到执行这个声明的模块的全局符号表。
21.from…import* 语句
把一个模块的所有内容全都导入到当前的命名空间也可行
from modname import *
提供了一个简单的方法来导入一个模块中的所有项目。
(这种声明不被过多地使用)
22.匿名函数
使用 lambda 创建匿名函数。
lambda只是一个表达式,函数体简单。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
lambda函数的语法只有这一个语句:
lambda [arg1 [,arg2,.....argn]]:expression
23.python rsa 一些常用代码
rsa计算密钥长度的方式是 common.byte_size(rsa_key.n)
rsa加密:rsa.encrypt(message, pub_key)
rsa解密:rsa.decrypt(crypto, priv_key)
rsa签名:rsa.sign(message, priv_key, hash)
rsa验签:rsa.verify(message, signature, pub_key)
rsa默认没有私钥加密,公钥解密的方法(加解密传入错误的key会报错,如果想实现私钥加密,公钥解密可以自行模拟底层代码实现)
签名只能用私钥(用到私钥的n值,公钥没有n值,n、d、e具体什么意思请百度RSA算法原理)
rsa加载公钥和私钥的方法不同
rsa私钥签名时,需要传入的是不是具体的摘要信息(字符串),而是签名信息的hash对象(对象)
不同版本的rsa验签成功之后返回结果不一样,有的是True,有的是返回生成摘要算法名:如sha1
24.python rsa 知识
加密是为了保证传输内容隐私,签名是为了保证消息真实性。
服务器存私钥,客户端存公钥。(服务器和客户端关系可以考虑为 1:N)
客户端往服务器传输内容,更多考虑是隐私性,所以公钥签名、私钥解密。
服务器往客户端传输内容,更多考虑真实性,所以私钥签名,公钥验签。
消息的摘要生的算法常用的是MD5或者SHA1,消息内容不一样,生成的摘要信息一定不一样。
真实性的考虑一方面是内容由私钥拥有者发出,另一方面内容在传输过程中没有改变过,所以签名的对象是传输信息生成的消息摘要(摘要内容短,签名也会快些)。
每次加密的长度需要小于密钥长度-特殊位(128位公钥,最长可加密128-11=117位明文)。
每次解密的长度需要小于密钥的长度(128位私钥解密,解密密文长度需要小于等于128位)。
如果加解密内容过长,就需要分段加密、解密。
PEM格式的密钥为base64位文本格式。
25.python rsa 具体运算
RSA是一种算法,并且广泛应用于现代,用于保密通信。
RSA算法涉及三个参数,n,e,d,其中分为私钥和公钥,私钥是n,d,公钥是n,e
n是两个素数的乘积,一般这两个素数在RSA中用字母p,q表示e是一个素数
d是e模 varphi(n) 的逆元,CTF的角度看就是,d是由e,p,q可以求解出的
一般CTF就是把我们想要获得的flag作为明文,RSA中表示为m。然后通过RSA加密,得到密文,RSA中表示为C。
加密过程
c=m^e mod n
m=c^d mod n
基础RSA加密脚本
from Crypto.Util.number import * import gmpy2 msg = 'flag is :testflag' hex_msg=int(msg.encode("hex"),16) print(hex_msg) p=getPrime(100) q=getPrime(100) n=p*q e=0x10001 phi=(p-1)*(q-1) d=gmpy2.invert(e,phi) print("d=",hex(d)) c=pow(hex_msg,e,n) print("e=",hex(e)) print("n=",hex(n)) print("c=",hex(c))
要用到gmpy2这个库
基础RSA解密脚本
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import binascii
import gmpy2
n=0x80b32f2ce68da974f25310a23144977d76732fa78fa29fdcbf 16-10
p=780900790334269659443297956843
q=1034526559407993507734818408829
e=0x10001
c=0x534280240c65bb1104ce3000bc8181363806e7173418d15762
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(hex(m))
print(binascii.unhexlify(hex(m)[2:].strip("L")))
26.python rsa 共模攻击
若干次加密,e不同,n相同,m相同。就可以在不分解n和求d的前提下,解出明文m。
首先,两个加密指数互质:
gcd(e1,e2)=1
即存在s1、s2使得:
s1+*e1+s2*e2=1
又因为:
c1≡m^e1 mod n
c2≡m mod n
代入化简可得:
c1^s1 * c2^s2 ≡ m mod n
即可求出明文
完整解题脚本
import sys
import binascii
sys.setrecursionlimit(1000000)
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
c1=0x?????
e1=0x??????
c2=0x??????
e2=0x?????
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
print(m)
print (binascii.unhexlify(hex(m)[2:].strip("L")))

浙公网安备 33010602011771号