2013-05-06 3 views
7

Я занимаюсь программированием, и я схожу с ума с одной из проблем. В этом случае мне нужно вычислить MD5 строки. Строка приведена в следующем виде:Хэширование одного и того же символа несколько раз

n[c]: Где n - номер и c - персонаж. Например: b3[a2[c]] =>baccaccacc

Все шло нормально, пока я не получил следующую строку:

1[2[3[4[5[6[7[8[9[10[11[12[13[a]]]]]]]]]]]]]

Это строки превращается в строку с 6227020800 a «с. Эта строка больше 6 ГБ, поэтому практически невозможно вычислить ее в практическое время. Итак, вот мой вопрос:

Есть ли какие-либо свойства MD5, которые я могу использовать здесь?

Я знаю, что должна быть форма, чтобы сделать это за короткое время, и я подозреваю, что это должно быть связано с тем фактом, что вся строка имеет тот же символ, который повторяется несколько раз.

+0

Это, вероятно, будет простым, обратным поиском и найти первый возникающий '[', замените символ после ('a') на число infront' ['(' 13', поэтому '13 * 'a ''), то боль в этой строке в переменной, посмотрите на следующий' '' 'и возьмите' mystoredstring * num' и т. д. – Torxed

+0

@Torxed Этот вопрос касается не создания реальной строки из ее компактного представления (которое было бы буква 6227020800 времени, как уже указывал ОП), но и об эффективном вычислении хэша MD5 такой большой строки. – Carsten

+0

Я могу рассчитать его примерно за 14 секунд времени процессора на моей машине. Как вы определяете «практическое время»? – Aya

ответ

3

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

Вот пример с использованием однопроходной парсер:

import re, sys, md5 

def p(s, pos, callBack): 
    while pos < len(s): 
    m = re.match(r'(d+)[', s[pos:]) 
    if m: # repetition? 
     number = m.group(1) 
     for i in range(int(number)): 
     endPos = p(s, pos+len(number)+1, callBack) 
     pos = endPos 
    elif s[pos] == ']': 
     return pos + 1 
    else: 
     callBack(s[pos]) 
     pos += 1 
    return pos + 1 

digest = md5.new() 
def feed(s): 
    digest.update(s) 
    sys.stdout.write(s) 
    sys.stdout.flush() 

end = p(sys.argv[1], 0, feed) 
print 
print "MD5:", digest.hexdigest() 
print "finished parsing input at pos", end 
+0

Да, это свойство, которое я искал. Спасибо за неоценимую помощь – Lars

0

Все функции хеширования предназначены для работы с байтовых потоков, так что вы не должны сначала создать всю строку, а после этого хэша это - вы должны генератор записи, который создает фрагменты строковых данных и передает его в контекст MD5. И, MD5 использует 64-байтовый (или char) буфер, поэтому было бы неплохо дать 64-байтовые фрагменты данных в контексте.

0

Воспользуйтесь хорошими свойствами хешей:

import hashlib 
cruncher = hashlib.md5() 
chunk = 'a' * 100 
for i in xrange(100000): 
    cruncher.update(chunk) 
print cruncher.hexdigest() 

Щипните количество раундов (х = 10000) и длину порции (у = 100), так что х * у = 13 !. Дело в том, что вы кормите алгоритм кусками вашей строки (каждый один символ x), один за другим, для y раз.

Смежные вопросы