Python未知模式查找

时间:2011-06-12 21:09:44

标签: python find design-patterns

好的,基本上我想要的是通过重用代码来压缩文件,然后在运行时替换丢失的代码。我想出的是非常丑陋和缓慢,至少它是有效的。问题是该文件没有特定的结构,例如'aGVsbG8 = \ n',因为你可以看到它的base64编码。我的功能非常慢,因为文件的长度是1700+,它检查当时的模式1个字符。请帮助我使用新的更好的代码或至少帮助我优化我得到的:)。欢迎任何有用的东西!顺便说一句,我已经尝试过压缩库,但它们的压缩效果并不如我丑陋的功能。

def c_long(inp, cap=False, b=5):
    import re,string
    if cap is False: cap = len(inp)
    es = re.escape; le=len; ref = re.findall; ran = range; fi = string.find
    c = b;inpc = inp;pattern = inpc[:b]; l=[]
    rep = string.replace; ins = list.insert
    while True:
        if c == le(inpc) and le(inpc) > b+1: c = b; inpc = inpc[1:]; pattern = inpc[:b]
        elif le(inpc) <= b: break
        if c == cap: c = b; inpc = inpc[1:]; pattern = inpc[:b]
        p = ref(es(pattern),inp)
        pattern += inpc[c]
        if le(p) > 1 and le(pattern) >= b+1:
            if l == []: l = [[pattern,le(p)+le(pattern)]]
            elif le(ref(es(inpc[:c+2]),inp))+le(inpc[:c+2]) < le(p)+le(pattern):
                x = [pattern,le(p)+le(inpc[:c+1])]
                for i in ran(le(l)):
                    if x[1] >= l[i][1] and x[0][:-1] not in l[i][0]: ins(l,i,x); break
                    elif x[1] >= l[i][1] and x[0][:-1] in l[i][0]: l[i] = x; break
                inpc = inpc[:fi(inpc,x[0])] + inpc[le(x[0]):]
                pattern = inpc[:b]
                c = b-1
        c += 1
    d = {}; c = 0
    s = ran(le(l))
    for x in l: inp = rep(inp,x[0],'{%d}' % s[c]); d[str(s[c])] = x[0]; c += 1
    return [inp,d]

def decompress(inp,l): return apply(inp.format, [l[str(x)] for x in sorted([int(x) for x in l.keys()])])

2 个答案:

答案 0 :(得分:2)

压缩base64编码数据的最简单方法是首先将其转换为二进制数据 - 这将节省25%的存储空间:

>>> s = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=\n"
>>> t = s.decode("base64")
>>> len(s)
37
>>> len(t)
26

在大多数情况下,您可以使用某种压缩算法进一步压缩字符串,例如t.encode("bz2")t.encode("zlib")

对您的代码的一些评论:有很多因素使代码难以阅读:间距不一致,行过长,无意义的变量名称,单一代码等等。示例:您的decompress()函数可以被等同地写成

def decompress(compressed_string, substitutions):
    subst_list = [substitutions[k] for k in sorted(substitutions, key=int)]
    return compressed_string.format(*subst_list)

现在它的作用已经非常明显了。您可以更进一步:为什么substitutions是一个包含字符串键"0""1"等的字典?使用字符串而不是整数不仅奇怪 - 你根本不需要密钥!一个简单的列表就可以了,decompress()将简化为

def decompress(compressed_string, substitutions):
    return compressed_string.format(*substitutions)

您可能认为所有这些都是次要的,但如果您使其余代码具有相同的可读性,您将自己找到代码中的错误。 (错误 - 它会导致"abcdefgabcdefg"和许多其他字符串崩溃。)

答案 1 :(得分:1)

通常会通过针对文本优化的压缩算法来抽取程序,然后通过exec运行,例如

code="""..."""
exec(somelib.decompress(code), globals=???, locals=???)

可能已经压缩了.pyc / .pyo个文件,可以通过创建一个x="""aaaaaaaa"""来检查,然后将长度增加到x="""aaaaaaaaaaaaaaaaaaaaaaa...aaaa"""并且看看尺寸是否明显变化。