实现Base64解码和命令分发器

实现Base64解码

alphabet = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

def base64decode(src:bytes):
    ret = bytearray()
    length = len(src)

    step =4 #对齐的,每次取4个
    for offset in range(0,length,step):
        tmp = 0x00
        block = src[offset:offset+step]

        #开始移位计算
        for i,c in enumerate(reversed(block)):
            #替换字符为序号
            index = alphabet.find(c)
            if index==-1:
                continue #找不到就是0,不用移位相加了
            tmp+=index<< i*6

        ret.extend(tmp.to_bytes(3,"big"))
    return bytes(ret.rstrip(b"\x00")) #把右边的\x00去掉,不可变

#base64的decode
txt = "TWFu"
txt = "TWE="
txt = "TQ="
txt = "TWFuTWE="
txt = "TWFuTQ="
txt = txt.encode()
print(txt)
print(base64decode(txt).decode())

#base64实现
import base64
print(base64.b64encode(txt).decode())

结果为:
b'TWFuTQ='
Man4
VFdGdVRRPQ==

改进

  1. reversd可以不需要
  2. alphabet.find效率低
from collections import OrderedDict

base_tb1 = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
alphabet = OrderedDict(zip(base_tb1,range(61)))#用有序字典记录顺序和查询提升效率

def base64decode(src:bytes):
    ret = bytearray()
    length = len(src)

    step =4 #对齐的,每次取4个
    for offset in range(0,length,step):
        tmp = 0x00
        block = src[offset:offset+step]

        #开始移位计算
        for i in range(4):
            index = alphabet.get(block[-i-1])
            if index is not None:
                tmp+=index<<i*6
            #找不到,不用移位相加了
            #替换字符为序号

        ret.extend(tmp.to_bytes(3,"big"))
    return bytes(ret.rstrip(b"\x00")) #把右边的\x00去掉,不可变

#base64的decode
txt = "TWFu"
#txt = "TWE="
#txt = "TQ="
#txt = "TWFuTWE="
#txt = "TWFuTQ="
txt = txt.encode()
print(txt)

print(base64decode(txt).decode())

#base64实现
import base64
print(base64.b64encode(txt).decode())

结果为:

b'TWFu'
Man
VFdGdQ==

2.完善命令分发器,实现函数可以带任意参数(可变参数除外),解析参数并要求用户输入

即解决下面的问题

#自定义函数

@reg("xpc")
def foo1(x,y):
    print("xpc",x,y)
    
@reg("python")
def foo2(a,b=100):
    print("python11",a,b)

思路,可以有2种方式

1.注册的时候,固定死,@reg("py",200,100),可以认为@reg("py",200,100)和@reg("py",300,100)是不同的函数,可以用partial函数。

2.运行时,在输入cmd的时候,逗号分隔,获取参数。

至于函数验证,以后实现。

一般用户都喜欢使用单纯一个命令如mag,然后直接显示想要的结果,所以采用第一种方式。

from functools import partial

#自定义函数可以有任意参数,可变参数,keyword_only除外

def command_dispatcher():
    #构建全局字典
    cmd_tb1 = {}

    #注册函数
    def reg(cmd,*args,**kwargs):
        def _reg(fn):
            func = partial(fn,*args,**kwargs)
            cmd_tb1[cmd] = func
            return func
        return _reg

    #缺省函数

    def default_func():
        print("unknown command")

    #调度器
    def dispatcher():
        while True:
            cmd = input("please input cmd>>")
            #退出条件
            if cmd.strip()=="quit":
                return
            cmd_tb1.get(cmd,default_func)()

    return reg,dispatcher

reg,dispatcher = command_dispatcher()

#自定义函数
@reg("xpc",z=200,y=300,x=100)
def foo1(x,y,z):
    print("xpc",x,y,z)

@reg("python",300,b=400)
def foo2(a,b=100):
    print("python",a,b)

dispatcher()

 

posted on 2019-12-10 15:39  xpc199151  阅读(365)  评论(0编辑  收藏  举报

导航