Граница окна рендеринга на определенной стороне в XMonad

Знание контрольной суммы детали не помогает вычислить контрольную сумму целого, поэтому вам придется вычислять контрольную сумму всех возможных перестановок до тех пор, пока вы не найдете нужную. Если у вас есть n частей, то есть n! (факториал n)) перестановок, и если все они одинаково вероятны, Вам придется обрабатывать n!/2 в среднем до тех пор, пока Вы не найдете нужную перестановку.

Когда вам нужно вычислить контрольную сумму нескольких строк с одним и тем же префиксом, вы можете сэкономить время, сохранив внутреннее состояние функции MD5. Например, с тремя частями (X, Y, Z), вам нужно будет вычислить MD5(X+Y+Z), MD5(X+Z+Y), MD5(Y+X+Z), MD5(Y+Z+X), MD5(Z+X+Y) и MD5(Z+Y+X). Если вы начинаете вычисление MD5(X,...), то дублируйте состояние и закончите вычисление для обоих суффиксов Y+Z и Z+Y. Но для этого нужно внутреннее состояние, а не вывод, и большинство инструментов не дают доступ к внутреннему состоянию. Хэш-функция

Python's hashlib предоставляет метод copy для копирования внутреннего состояния хэш-функции. Она также имеет итератор для перечисления перестановок в своей стандартной библиотеке.

#!/usr/bin/env python2
import hashlib, itertools, sys

def look_for_permutation(goal, filenames):
    n = len(filenames)
    files = map(open, filenames)
    previous = map(lambda _: None, filenames)
    states = [hashlib.md5()] + [None] * (n-2)
    for current in itertools.permutations(files):
        i = 0
        while current[i] == previous[i]:
            i += 1
        state = states[i].copy()
        for f in current[i:n-2]:
            state.update(f.read())
            i += 1
            states[i] = state.copy()
            f.seek(0)
        state.update(current[n-2].read())
        current[n-2].seek(0)
        state.update(current[n-1].read())
        if state.hexdigest() == goal:
            return current
        current[n-1].seek(0)
        previous = current
    return None

if __name__ == '__main__':
    result = look_for_permutation(sys.argv[1], sys.argv[2:])
    if result:
        for f in result: print f.name
        sys.exit(0)
    else:
        sys.exit(1)

Этот сценарий оптимизирует вычисления хэшей, но многократно считывает содержимое файла. Если содержимое файлов помещается в память, то можно сделать это немного быстрее, загрузив файлы раз и навсегда.

0
27.12.2017, 18:00
0 ответов

Теги

Похожие вопросы