2018-05-30

日常随笔录之解决几个小问题

代码呈上:

'''
import base64
import random
import time

from flask import Flask, request

app = Flask(__name__)

users = {
    "lisir": ["123456"]
}

def gen_token(uid):
    token = base64.b64encode(':'.join([str(uid), str(random.random()), str(time.time()+7200)]))
    print(token)
    users[uid].append(token)
    return token


def verify_token(token):
    _token = base64.b64decode(token)
    if not users.get(_token.split(':')[0])[-1] == token:
        return -1
    if float(_token.split(':')[-1])>=time.time():
        return 1
    else:
        return 0

@app.route('/index', methods=['GET', 'POST'])
def index():
    print(request.headers)
    return('hello world')

@app.route('/login', methods=['GET', 'POST'])
def login():
    # uid, pw = base64.b64decode(request.headers['Authorization'].split(' ')[-1]).split(':')

t = request.headers['Authorization']
print(t)
bt = t.split(' ')[-1]
print(bt)
btt = base64.b64decode(bt)
print(btt)
gen_token(btt)

return gen_token(btt)

if users.get(uid)[0] == pw:
    return gen_token(uid)
else:
    return 'error'

@app.route('/test1', methods=['GET', 'POST'])
def test1():
    token = request.args.get('token')
    if verify_token(token) == 1:
        return 'data'
    else:
        return 'error'

if __name__ == '__main__':
    app.run(debug=True, port=5000)
'''

request_t.py

  '''
    import requests

    r = requests.get('http://127.0.0.1:5000/login', auth=              ('lisir', '123456'))
    print(r.text)

  # token = r.text
  # r = requests.get('http://127.0.0.1:5000/test1',       params={'token': token})
  # print(r.text)

  '''

Base64是一种用64个字符来表示任意二进制数据的方法
常用于在URL、Cookie、网页中传输少量二进制数据。
Base64的原理很简单,首先,准备一个包含64个字符的数组, 然后,对二进制数据进行处理,每3个字节一组,一共是3x8=24bit,划为4组,每组正好6个bit,我们得到4个数字作为索引,然后查表,获得相应的4个字符,就是编码后的字符串。
Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%
如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

    '''
    import base64
    base64.b64encode('binary\x00string')
    'YmluYXJ5AHN0cmluZw=='
     base64.b64decode('YmluYXJ5AHN0cmluZw==')
     'binary\x00string'
    '''

由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种"url safe"的base64编码,其实就是把字符+和/分别变成-和_:

    '''
     base64.b64encode('i\xb7\x1d\xfb\xef\xff')
     'abcd++//'
     base64.urlsafe_b64encode('i\xb7\x1d\xfb\xef\xff')
     'abcd--__'
     base64.urlsafe_b64decode('abcd--__')
    'i\xb7\x1d\xfb\xef\xff'
     '''

由于=字符也可能出现在Base64编码中,但=用在URL、Cookie里面会造成歧义,所以,很多Base64编码后会把=去掉
去掉=后怎么解码呢?因为Base64是把3个字节变为4个字节,所以,Base64编码的长度永远是4的倍数,因此,需要加上=把Base64字符串的长度变为4的倍数,就可以正常解码了。

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

   '''
   base64.b64decode('YWJjZA==')
  'abcd'
   base64.b64decode('YWJjZA')
  Traceback (most recent call last):
    ...
  TypeError: Incorrect padding
  safe_b64decode('YWJjZA')
  'abcd'
   '''

random
import random
random.shuffle(list)随机排序list中的数据
random.randint(0, 9)随机输出0-9之间的一个数字
random.sample(list,10) #输出10个固定长度的组合字符
random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0
random.uniform的函数原型为:random.uniform(a, b),用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限
random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b


time
time模块--时间获取和转换

     time模块提供各种时间相关的功能
    与时间相关的模块有:time,datetime,calendar

time.altzone

  返回格林威治西部的夏令时地区的偏移秒数,如果该地区在格林威治东部会返回负值(如西欧,包括英国),对夏令时启用地区才能使用

time.asctime([t])

  接受时间元组并返回一个可读的形式"Tue May 30 17:17:30 2017"(2017年5月30日周二17时17分30秒)的24个字符的字符串

time.clock()

  用以浮点数计算的秒数返回当前的CPU时间,用来衡量不同程序的耗时,比time.time()更有用
  python3.3以后不被推荐使用,该方法依赖操作系统,建议使用per_counter(返回系统运行时间)或process_time(返回进程运行时间)代替

time.ctime([secs])

  作用相当于asctime(localtime(secs)),未给参数相当于asctime()

time.gmtime([secs])

  接收时间辍(1970纪元年后经过的浮点秒数)并返回格林威治天文时间下的时间元组t(t.tm_isdst始终为0)

time.daylight

  如果夏令时被定义,则该值为非零

time.localtime([secs])

  接收时间辍(1970纪元年后经过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取为0或1,取决于当地当时是不是夏令时)

time.mktime(t)

  接受时间元组并返回时间辍(1970纪元年后经过的浮点秒数)

time.perf_counter()

   返回计时器的精准时间(系统的运行时间),包含整个系统的睡眠时间.由于返回值的基准点是未定义的,所以,只有连续调用的结果之间的差才是有效的

time.process_time()

  返回当前进程执行CPU的时间总和,不包含睡眠时间.由于返回值的基准点是未定义的,所以只有连续调用的结果之间的差才是有效的

time.sleep(secs)

 推迟调用线程的运行,secs的单位是秒

time.strftime(format[,t])

  把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串.如果t未指定,将传入time.localtime(),如果元组中任命一个元素越界,将会抛出ValueError异常
format格式如下:
%a      本地(local)简化星期名称
%A      本地完整星期名称
%b      本地简化月份名称
%B      本地完整月份名称
%c      本地相应的日期和时间表示
%d      一个月中的第几天(01-31)
%H      一天中的第几个小时(24小时制,00-23)
%l      一天中的第几个小时(12小时制,01-12)
%j      一年中的第几天(01-366)
%m      月份(01-12)
%M      分钟数(00-59)
%p      本地am或者pm的相应符
%S      秒(01-61)
%U      一年中的星期数(00-53,星期天是一个星期的开始,第一个星期天之前的所有天数都放在第0周)
%w      一个星期中的第几天(0-6,0是星期天)
%W      和%U基本相同,不同的是%W以星期一为一个星期的开始
%x      本地相应日期
%X      本地相应时间
%y      去掉世纪的年份(00-99)
%Y      完整的年份       
%z      用+HHMM或者-HHMM表示距离格林威治的时区偏移(H代表十进制的小时数,M代表十进制的分钟数)
%Z      时区的名字(如果不存在为空字符)
%%      %号本身
        %p只有与%I配合使用才有效果
        当使用strptime()函数时,只有当在这年中的周数和天数被确定的时候%U和%W才会被计算

time.strptime(string[,format])

    把一个格式化时间字符串转化为struct_time,实际上它和strftie()是逆操作

time.time()

  返回当前时间的时间戳(1970元年后的浮点秒数)

jion

request.headers
request.args.get

request请求总体分为两类:

1.get请求

访问时会在地址栏直接显示参数不安全,且参数大小比较小。

2.post请求

参数不显示在地址栏,一般用户注册、登录都通过post请求完成。

flask获取参数方式:

request.form.get("key", type=str, default=None) 获取表单数据

request.args.get("key") 获取get请求参数

request.values.get("key") 获取所有参数

你可能感兴趣的:(2018-05-30)