Python基础

为南京理工大学网络安全爱好者协会寒假集训写的Python入门材料

目录


pythonchallenge题解

这里提供的示例代码由笔者编写,涉及的高级特性较少。

每题都存在多种解法,可参考官方题解(解题后可获得阅读权限)。

level0

题目链接

官方题解

思路:

  • 计算2的38次方
  • 直接在交互模式进行计算

示例代码:

1
2
>>> pow(2,38)
274877906944L

level1

题目链接

官方题解

思路:

  • 整段话在英文字母范围内进行一次 rot2 运算,即可得到明文

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- conding: utf-8 -*-
raw = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
print(raw + '\n')
def rot2(raw):
for ch in raw:
if ord(ch) in range(ord('a'),ord('z')+1):
if ch == 'y':
print('a', end = '')
elif ch == 'z':
print('b', end = '')
else:
print(chr(ord(ch)+2), end = '')
else:
print(ch, end = '')
rot2(raw)
print('\n')
rot2('map')

level2

题目链接

官方题解

思路:

  • 右键源码,发现提示和一堆符号
  • 提示查找少见的字符
  • 脚本统计

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding: utf-8 -*-
from functools import reduce

with open('ocr.txt', 'r') as f:
#print(f.read())
characters = {}
for ch in f.read():
if ch in characters:
characters[ch] += 1
else:
characters[ch] = 1
print(sorted(characters.items(), key=lambda i:i[1]))
#
with open('ocr.txt', 'r') as f:
#print(f.read())
characters = []
for ch in f.read():
if ch in characters:
continue
else:
characters.append(ch)
#print(characters)
print(reduce(lambda x,y:x+y, characters))

level3

题目链接

官方题解

思路:

  • 提示小写字母左右两侧都满足有且仅有三个大写字母与之相邻
  • 右键源码看到乱码,保存到文件
  • 遍历或正则匹配

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# -*- coding: utf-8 -*-
import re
# 正则
def judge_line2(line):
result = (re.compile(r'[a-z]+[A-Z]{3}[a-z]{1}[A-Z]{3}[a-z]+?')).findall(line) #懒惰匹配
if result != []:
print(result[0][-5:-4], end = '')
# 遍历
def judge_line(line):
i = 0
while i < len(line)-9:
cut = line[i:i+9]
flag = False #
if not ord(cut[0]) in range(ord('a'),ord('z')+1):
flag = True #不符合
if not ord(cut[4]) in range(ord('a'),ord('z')+1):
flag = True
if not ord(cut[8]) in range(ord('a'),ord('z')+1):
flag = True
for j in range(1,4):
if not ord(cut[j]) in range(ord('A'),ord('Z')+1):
flag = True
break
for j in range(5,8):
if not ord(cut[j]) in range(ord('A'),ord('Z')+1):
flag = True
break
if not flag: #符合
#print(cut)
print(cut[4], end = '')
else:
pass
#print(cut[3] + '不符合')
i += 1

if __name__ == '__main__':
with open('equality.txt', 'r') as f:
for lines in f.readlines():
judge_line(lines)
print('')
with open('equality.txt', 'r') as f:
for lines in f.readlines():
judge_line2(lines)

level4

题目链接

官方题解

思路:

  • GET方法传入一个nothing,返回下一个nothing值
  • 写脚本自动提取、发送
  • 请求频率过高会导致中断
  • 中途出现了pattern变化,手动访问解决

实例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding:utf-8 -*-
import requests,re,time,sys
number = 55205
number = sys.argv[1] # 从传入值开始访问
for count in range(400):
r = requests.get('http://www.pythonchallenge.com/pc/def/linkedlist.php', params = {'nothing': number})
#print(r.url)
#print(r.text)
resultStr = (re.compile('and the next nothing is [0-9]+')).findall(r.text)[0]
if resultStr == r.text:
print(resultStr)
else:
print('pattern changed')
break
number = resultStr[24:]
time.sleep(2)

level5

题目链接

官方题解

思路:

  • 右键源码发现 banner.p ,下载下来,发现是乱码
  • python序列化得到的二进制文件
  • 反序列化,发现是字符和出现次数
  • 依次按次数打印字符

示例代码:

1
2
3
4
5
6
7
8
9
10
# -*- coding: utf-8 -*-
import pickle
with open('banner.p', 'rb') as f:
r = pickle.load(f)
#print(r)
for line in r:
for t in line:
for count in range(t[1]):
print(t[0], end = '')
print('')

level6

题目链接

官方题解

思路:

  • 右键源码,发现zip,修改URL下载channel.zip文件
  • 压缩文件里有很多数字命名的txt文档,文档中是下一个文档的名称
  • 脚本提取、遍历
  • 得到提示,提取压缩文件的注释
  • 脚本遍历、输出

示例代码:

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-
import re, zipfile
nothing = 90052

while True:
f0 = zipfile.ZipFile('channel.zip', 'r')
print((f0.getinfo(str(nothing) + '.txt').comment).decode(), end = '')
with open('./channel/' + str(nothing) + '.txt') as f:
#print(f.read())
nothing = (re.compile('Next nothing is [0-9]+')).findall(f.read())[0][16:]
#print(nothing)

level7

题目链接

官方题解

思路:

  • 图片中的横条由7*9的小方块排成一行组成
  • 提取每个方块的rgb值,转换成字符输出

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding:utf-8 -*-
# 笔者用了多个工具对图片进行操作(没有PS),导致一些色块出现偏差
from PIL import Image
img = Image.open('oxygen.jpg')
width, height = img.size
#print(width)
#print(height)
pixel = img.load()
i = 4
while i < 608:
print(chr(pixel[i,0]), end = '')
#print(img.getpixel((i,0)))
i += 7

print('')
print(list(map(chr, [105, 110, 116, 101, 103, 114, 105, 116, 121])))

level8

题目链接

官方题解

思路:

  • 点击图片出现登录框
  • 右键源码,发现un、pw分别对应BZ开头字符串
  • bzip解压,得到username和password

示例代码:

1
2
3
4
5
6
# -*- coding: utf-8 -*-
import bz2
un = b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw = b'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'
print(bz2.decompress(un))
print(bz2.decompress(pw))

level9

题目链接

官方题解

思路:

  • level8中右键源码发现有list没有用到,level9中图片上出现莫名的黑点,网页标题提示连点
  • level9右键源码,发现两个长度不同的list,提示两个相加
  • 根据两个list分别绘图再叠加

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding:utf-8 -*-
from PIL import ImageDraw,Image
first = [146,399,163,403,170,393,169,391,166,386,170,381,170,371,170,355,169,346,167,335,170,329,170,320,170,
310,171,301,173,290,178,289,182,287,188,286,190,286,192,291,194,296,195,305,194,307,191,312,190,316,
190,321,192,331,193,338,196,341,197,346,199,352,198,360,197,366,197,373,196,380,197,383,196,387,192,
389,191,392,190,396,189,400,194,401,201,402,208,403,213,402,216,401,219,397,219,393,216,390,215,385,
215,379,213,373,213,365,212,360,210,353,210,347,212,338,213,329,214,319,215,311,215,306,216,296,218,
290,221,283,225,282,233,284,238,287,243,290,250,291,255,294,261,293,265,291,271,291,273,289,278,287,
279,285,281,280,284,278,284,276,287,277,289,283,291,286,294,291,296,295,299,300,301,304,304,320,305,
327,306,332,307,341,306,349,303,354,301,364,301,371,297,375,292,384,291,386,302,393,324,391,333,387,
328,375,329,367,329,353,330,341,331,328,336,319,338,310,341,304,341,285,341,278,343,269,344,262,346,
259,346,251,349,259,349,264,349,273,349,280,349,288,349,295,349,298,354,293,356,286,354,279,352,268,
352,257,351,249,350,234,351,211,352,197,354,185,353,171,351,154,348,147,342,137,339,132,330,122,327,
120,314,116,304,117,293,118,284,118,281,122,275,128,265,129,257,131,244,133,239,134,228,136,221,137,
214,138,209,135,201,132,192,130,184,131,175,129,170,131,159,134,157,134,160,130,170,125,176,114,176,
102,173,103,172,108,171,111,163,115,156,116,149,117,142,116,136,115,129,115,124,115,120,115,115,117,
113,120,109,122,102,122,100,121,95,121,89,115,87,110,82,109,84,118,89,123,93,129,100,130,108,132,110,
133,110,136,107,138,105,140,95,138,86,141,79,149,77,155,81,162,90,165,97,167,99,171,109,171,107,161,
111,156,113,170,115,185,118,208,117,223,121,239,128,251,133,259,136,266,139,276,143,290,148,310,151,
332,155,348,156,353,153,366,149,379,147,394,146,399]
second = [156,141,165,135,169,131,176,130,187,134,191,140,191,146,186,150,179,155,175,157,168,157,163,157,159,
157,158,164,159,175,159,181,157,191,154,197,153,205,153,210,152,212,147,215,146,218,143,220,132,220,
125,217,119,209,116,196,115,185,114,172,114,167,112,161,109,165,107,170,99,171,97,167,89,164,81,162,
77,155,81,148,87,140,96,138,105,141,110,136,111,126,113,129,118,117,128,114,137,115,146,114,155,115,
158,121,157,128,156,134,157,136,156,136]

img = Image.new('RGB', (500, 500))
draw = ImageDraw.Draw(img)
draw.line(first)
draw.line(second)
img.show()

level10

题目链接

官方题解

思路:

  • 点击牛跳转到sequence.txt,文件中是一段list,只有开头
  • 页面提示求第30个元素的长度
  • 发现规律:后一个元素由前一个元素递推得到
  • 编写脚本,遍历前一个元素,每连续x几个n,对应后一个元素中的‘xn’
  • 注意循环退出时的处理

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# -*- coding:utf-8 -*-
def next(former):
result = ''
i = 1
ch = former[0]
count = 1
while True:
if i == len(former):
break
elif ch == former[i]:
count += 1
i += 1
else:
result += str(count) + ch
count = 1
ch = former[i]
#print('next:' + ch)
i += 1
#print('result:' + result)
result += str(count) + ch
#print(result)
return result

if __name__ == '__main__':
#next('111221')
former = '1'
for count in range(30):
former = next(former)
#print(former)
print(len(former))

常用库

requests

web常用,实现HTTP数据发送、接收,用于需要发送大量请求的地方,如SQL盲注、fuzz测试等

pwntools

pwn常用,用于快速编写exploit

项目地址

文档地址

中文介绍

OpenCV Pillow

图像库, OpenCV为计算机视觉库,常用于图像识别,Pillow用于图像处理

PyAutoGui

用于挂机测试、运维等,模拟鼠标、键盘操作

项目地址

中文介绍

资料

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 目录
  2. 2. pythonchallenge题解
    1. 2.1. level0
    2. 2.2. level1
    3. 2.3. level2
    4. 2.4. level3
    5. 2.5. level4
    6. 2.6. level5
    7. 2.7. level6
    8. 2.8. level7
    9. 2.9. level8
    10. 2.10. level9
    11. 2.11. level10
  3. 3. 常用库
    1. 3.1. requests
    2. 3.2. pwntools
    3. 3.3. OpenCV Pillow
    4. 3.4. PyAutoGui
  4. 4. 资料
,