【廖雪峰Python习题集】常用内建模块

datetime:

假设你获取了用户输入的日期和时间如2015-1-21 9:01:30,以及一个时区信息如UTC+5:00,均是str,请编写一个函数将其转换为timestamp:

import  re
from  datetime import  datetime,timezone,timedelta

def to_timestamp(dt_str,tz_str):
    #str转换为datetime
    cday = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
    t = tz_str.split('C')
    t2 = t[1].split(':')
    hour = int(t2[0])
    mine = int(t2[1])
    #创建时区UTC时间
    tz_utc = timezone(timedelta(hours=hour,minutes=mine))
    #强制设置UTC时间
    dt = cday.replace(tzinfo=tz_utc)
    #返回timestamp时间
    return dt.timestamp()

if __name__ == "__main__":
    t1 = to_timestamp('2015-6-1 08:10:30','UTC+7:00')
    assert t1 == 1433121030.0 ,t1

    t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00')
    assert t2 == 1433121030.0 , t2

    print('Pass')
显示结果如下图所示:


base64:

请写一个能处理去掉=的base64解码函数:

import  base64

def safe_base64_decode(s):
    if not s.__contains__(b'=='):
        s = s + b'=='
    return base64.b64decode(s)

if __name__ =="__main__":

    assert b'abcd' == safe_base64_decode(b'YWJjZA==') ,safe_base64_decode('YWJjZA==')
    assert b'abcd' == safe_base64_decode(b'YWJjZA') , safe_base64_decode('YWJjZA')
    print('Pass')

显示结果如下图所示:



struct:

请编写一个bmpinfo.py,可以检查任意文件是否是位图文件,如果是,打印出图片大小和颜色数:

import struct
def bmpinfo(str):
    f = open(str, 'rb')
    s = f.read(30)
    h = struct.unpack('<ccIIIIIIHH', s)
    if h[0] == b'B' and (h[1] == b'M' or h[1] == b'A'):
        print(True)
        print('位图大小:', h[6], '*', h[7], '颜色数:', h[9])
    else:
        print(False)
        
if __name__ == "__main__":
    str = input('please the way of your file')
    bmpinfo(str)

显示结果如下图所示:

#是位图文件时:


#不是位图文件时:



hashlib:

练习1:

根据用户输入的口令,计算出存储在数据库中的MD5口令:


def calc_md5(password):
    pass

存储MD5的好处是即使运维人员能访问数据库,也无法获知用户的明文口令。

设计一个验证用户登录的函数,根据用户输入的口令是否正确,返回True或False:

db = {
    'michael': 'e10adc3949ba59abbe56e057f20f883e',
    'bob': '878ef96e86145580c38c87f0410ad153',
    'alice': '99b1c2188db85afee403b1536010c2c9'
}

def login(user, password):
    pass

采用MD5存储口令是否就一定安全呢?也不一定。假设你是一个黑客,已经拿到了存储MD5口令的数据库,如何通过MD5反推用户的明文口令呢?暴力破解费事费力,真正的黑客不会这么干。

考虑这么个情况,很多用户喜欢用123456888888password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:

'e10adc3949ba59abbe56e057f20f883e': '123456'
'21218cca77804d2ba1922c33e0151105': '888888'
'5f4dcc3b5aa765d61d8327deb882cf99': 'password'

这样,无需破解,只需要对比数据库的MD5,黑客就获得了使用常用口令的用户账号。

对于用户来讲,当然不要使用过于简单的口令。但是,我们能否在程序设计上对简单口令加强保护呢?

由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:

def calc_md5(password):
    return get_md5(password + 'the-Salt')

经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。

但是如果有两个用户都使用了相同的简单口令比如123456,在数据库中,将存储两条相同的MD5值,这说明这两个用户的口令是一样的。有没有办法让使用相同口令的用户存储不同的MD5呢?

如果假定用户无法修改登录名,就可以通过把登录名作为Salt的一部分来计算MD5,从而实现相同口令的用户也存储不同的MD5。

import hashlib
def get_md5(str):
    md5 = hashlib.md5()
    md5.update(str.encode('utf-8'))
    return md5.hexdigest()
def calc_md5(password):
    return get_md5(password)

db = {
    'michael':'e10adc3949ba59abbe56e057f20f883e',
    'bob':'878ef96e86145580c38c87f0410ad153',
    'alice':'99b1c2188db85afee403b1536010c2c9'
}

def login(user,password):
    if db[user] == password:
        return True
    else:
        return False

if __name__ == "__main__":
    username = input('please input username:')
    password = input('please input password:')
    pwd = calc_md5(password)
    print(login(username,pwd))

显示结果如下图所示:


练习2:

根据用户输入的登录名和口令模拟用户注册,计算更安全的MD5:

db = {}


def register(username,password):

      dn[username]  = get_md5(password + username + 'the-Salt')


然后,根据修改后的MD5算法实现用户登录的验证:

 def login(username,password):

      pass

import hashlib

def get_md5(str):
    md5 = hashlib.md5()
    md5.update(str.encode('utf-8'))
    return md5.hexdigest()
db = {}

def register(username,password):
    db[username] = get_md5(password + username + 'the-Salt')

def login(username,password):
    pwd = get_md5(password + username + 'the-Salt')
    if db[username] ==  pwd:
        return True
    else:
        return False

if __name__ == "__main__":
    username = input('please input username:')
    password = input('please input password:')
    register(username,password)
    print(login(username,password))

显示结果如下图所示:


XML:

请利用SAX编写程序解析Yahoo的XML格式的天气预报,获取当天和第二天的天气:

http://weather.yahooapis.com/forecastrss?u=c&w=2151330

参数w是城市代码,要查询某个城市代码,可以在weather.yahoo.com搜索城市,浏览器地址栏的URL就包含城市代码

from xml.parsers.expat import  ParserCreate
weather_dict = {}
which_day = 0
class WeatherSaxHandler(object):
    def start_element(self,name,attrs):
        global  weather_dict,which_day
        if name=='yweather:location':
            weather_dict['city']=attrs['city']
            weather_dict['country'] = attrs['country']

        if name == 'yweather:forecast':
            which_day+=1
            if which_day == 1 :
                weather = {
                    'text':attrs['text'],
                    'low':int(attrs['low']),
                    'high':int(attrs['high'])
                }
                weather_dict['today'] = weather
            elif which_day == 2:
                weather={
                    'text': attrs['text'],
                    'low':int(attrs['low']),
                    'high':int(attrs['high'])
                }
                weather_dict['tomorrow'] = weather

    def char_data(self,name):
        pass

    def end_element(self,text):
        pass

def parse_weather(xml):
    wea = WeatherSaxHandler()
    parser = ParserCreate()
    parser.StartElementHandler = wea.start_element
    parser.EndElementHandler = wea.end_element
    parser.CharacterDataHandler = wea.char_data
    parser.Parse(xml)
    return weather_dict

data = r'''<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
    <channel>
        <title>Yahoo! Weather - Beijing, CN</title>
        <lastBuildDate>Wed, 27 May 2015 11:00 am CST</lastBuildDate>
        <yweather:location city="Beijing" region="" country="China"/>
        <yweather:units temperature="C" distance="km" pressure="mb" speed="km/h"/>
        <yweather:wind chill="28" direction="180" speed="14.48" />
        <yweather:atmosphere humidity="53" visibility="2.61" pressure="1006.1" rising="0" />
        <yweather:astronomy sunrise="4:51 am" sunset="7:32 pm"/>
        <item>
            <geo:lat>39.91</geo:lat>
            <geo:long>116.39</geo:long>
            <pubDate>Wed, 27 May 2015 11:00 am CST</pubDate>
            <yweather:condition text="Haze" code="21" temp="28" date="Wed, 27 May 2015 11:00 am CST" />
            <yweather:forecast day="Wed" date="27 May 2015" low="20" high="33" text="Partly Cloudy" code="30" />
            <yweather:forecast day="Thu" date="28 May 2015" low="21" high="34" text="Sunny" code="32" />
            <yweather:forecast day="Fri" date="29 May 2015" low="18" high="25" text="AM Showers" code="39" />
            <yweather:forecast day="Sat" date="30 May 2015" low="18" high="32" text="Sunny" code="32" />
            <yweather:forecast day="Sun" date="31 May 2015" low="20" high="37" text="Sunny" code="32" />
        </item>
    </channel>
</rss>
'''
if __name__ == "__main__":
    weather = parse_weather(data)

    assert weather['city'] == 'Beijing', weather['city']
    assert weather['country'] == 'China', weather['country']
    assert weather['today']['text'] == 'Partly Cloudy', weather['today']['text']
    assert weather['today']['low'] == 20, weather['today']['low']
    assert weather['today']['high'] == 33, weather['today']['high']
    assert weather['tomorrow']['text'] == 'Sunny', weather['tomorrow']['text']
    assert weather['tomorrow']['low'] == 21, weather['tomorrow']['low']
    assert weather['tomorrow']['high'] == 34, weather['tomorrow']['high']
    print('Weather:', str(weather))

显示结果如下图所示:


HTMLParser:

找一个网页,例如:https://www.python.org/events/python-events,用浏览器查看源码并复制,然后尝试解析一下HTML,输出Python官网发布的会议时间,名称和地点

from html.parser import HTMLParser
from  html.entities import  name2codepoint
from urllib import request,parse

class MyHTMLParser(HTMLParser):
    in_title = False
    in_loca = False
    in_time = False
    times = []
    def handle_starttag(self, tag, attrs):
        if ('class','event-title') in attrs:
            self.in_title =True
        elif ('class','event-location') in attrs:
            self.in_loca = True
        elif tag =='time':
            self.in_time = True
            self.times=[]
    def handle_endtag(self, tag):
        if tag == 'h3':self.in_title = False
        if  tag =='span':self.in_loca = False
        if tag =='time':
            self.in_time = False
            print('Time:'+'-'.join(self.times))
    def handle_startendtag(self, tag, attrs):
        pass
    def handle_data(self, data):
        if self.in_title:
            print('Title: '+data.strip())
        if self.in_loca:
            print('Location: '+data.strip())
        if self.in_time:
            self.times.append(data)

    def handle_comment(self, data):
        pass
    def handle_entityref(self, name):
        pass
    def handle_charref(self, name):
        pass

if __name__ == "__main__":
    with request.urlopen('https://www.python.org/events/python-events') as f:
        data=f.read()
        req = data.decode('utf-8')

    parser = MyHTMLParser()
    parser.feed(req)
显示结果如下图所示:

F:\SoftWare\Python3.6\python.exe F:/SoftWare/Python3.6/Lib/urllib/explainHtml.py
Title: Django Girls Koforidua
Time:11 Nov. – 12 Nov. - 2017
Location: Koforidua, Ghana
Title: PuPPy, Seattle's Python user group's monthly meeting
Time:11 Nov.- 2017
Location: Seattle Humane, 13212 SE Eastgate Way, Bellevue, WA 98005, USA
Title: PyHPC 2017: 7th Workshop on Python for High-Performance and Scientific Computing
Time:12 Nov. – 13 Nov. - 2017
Location: Denver, CO, USA
Title: PyRoma Meetup
Time:14 Nov.- 2017
Location: Rome, Italy
Title: PyCon Jamaica 2017
Time:16 Nov. – 19 Nov. - 2017
Location: Kingston, Jamaica
Title: PyConAr 2017
Time:17 Nov. – 20 Nov. - 2017
Location: Haya De La Torre S/N, Córdoba, Cordoba, Argentina
Title: Django Girls Santa Barbara
Time:18 Nov. – 19 Nov. - 2017
Location: UCSB, Santa Barbara, California
Title: PyTexas 2017
Time:18 Nov. – 19 Nov. - 2017
Location: 119 Nueces St, Austin, TX 78701, USA
Title: PyCon Canada 2017
Time:18 Nov. – 22 Nov. - 2017
Location: Montreal, Quebec, Canada
Title: SciPy India 2017
Time:29 Nov. – 01 Dec. - 2017
Location: LCH, IIT Bombay, Powai, Mumbai, India
Title: Kiwi PyCon 2017
Time:02 Dec. – 04 Dec. - 2017
Location: Auckland, New Zealand
Title: Django Girls Pereira, Colombia
Time:02 Dec. – 03 Dec. - 2017
Location: Pereira, Colombia
Title: Django Girls Ibagué
Time:02 Dec. – 03 Dec. - 2017
Location: Ibagué, Colombia
Title: North Bay Python 2017
Time:02 Dec. – 04 Dec. - 2017
Location: Petaluma, California, USA
Title: PyCon Indonesia 2017
Time:09 Dec. – 10 Dec. - 2017
Location: Surabaya, Indonesia
Title: Indy Startup Row Pitch Event
Time:09 Jan. – 10 Jan. - 2018
Location: Indianapolis, IN, US
Title: Python Meeting Düsseldorf (PyDDF)
Time:17 Jan.- 2018
Location: Bürgerhaus, Bachstr. 145, 40217 Düsseldorf
Title: PyCascades 2018
Time:22 Jan. – 24 Jan. - 2018
Location: Vancouver, BC V6A, Canada
Title: PyCon Cameroon 2018
Time:24 Jan. – 29 Jan. - 2018
Location: Limbe, Cameroon
Title: Pythology One-Day Conference: Security Best Practices
Time:02 Feb. – 03 Feb. - 2018
Location: Fishers, IN, USA
Title: FOSDEM 2018
Time:03 Feb. – 05 Feb. - 2018
Location: ULB Campus du Solbosch, Av. F. D. Roosevelt 50, 1050 Bruxelles, Belgium
Title: PyCon Pune 2018
Time:08 Feb. – 12 Feb. - 2018
Location: Pune, India
Title: PyCon Colombia 2018
Time:09 Feb. – 12 Feb. - 2018
Location: Medellin, Colombia
Title: PyCon SK 2018
Time:09 March – 12 March - 2018
Location: Bratislava, Slovakia
Title: PyCon IT 9
Time:19 April – 23 April - 2018
Location: Hotel Mediterraneo - Lungarno del Tempio, 44, 50121 Firenze FI, Italy
Title: GeoPython 2018
Time:07 May – 10 May - 2018
Location: Basel, Switzerland
Title: PyCon US 2018
Time:09 May – 18 May - 2018
Location: Cleveland, Ohio, USA
Title: PyCon US 2019
Time:01 May – 10 May - 2019
Location: Cleveland, Ohio, USA

Process finished with exit code 0

urllib:

利用urllib读取XML,将XML一节的数据由硬编码改为由urllib获取:




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值