Создание контрольной суммы MD5 файла

Мне нравится ваш лаконичный код оценки и возврата результата в одной строке кода! Однако в вашем коде есть две проблемы: 1) вместо проверки целого числа вы смотрите последние две цифры 2) Порядок логической оценки неверен. Попробуйте этот простой код

def is_leap(year):
    y=int(year)
    return  y%400==0 or (y%100 != 0 and y%4==0)
year = input()
print(is_leap(year))
307
задан Sнаđошƒаӽ 12 April 2016 в 16:52
поделиться

3 ответа

Вы можете использовать hashlib.md5()

Обратите внимание, что иногда вы не сможете поместить весь файл в память. В этом случае вам придется последовательно считывать куски по 4096 байт и передавать их функции Md5:

def md5(fname):
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

Примечание: hash_md5.hexdigest() вернет hex-строку для представления дайджеста, если вам нужны только упакованные байты, используйте return hash_md5.digest(), чтобы не конвертировать обратно.

407
ответ дан 23 November 2019 в 01:18
поделиться

Я думаю, полагаясь, вызывают пакет, и md5sum двоичный файл немного более удобен, чем подпроцесс или md5 пакет

import invoke

def get_file_hash(path):

    return invoke.Context().run("md5sum {}".format(path), hide=True).stdout.split(" ")[0]

, Это, конечно, предполагает, что Вы имеете, вызывают и установленный md5sum.

0
ответ дан 23 November 2019 в 01:18
поделиться

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

один файл:

import hashlib
def file_as_bytes(file):
    with file:
        return file.read()

print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()

список файлов:

[(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]

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

[(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]

Если вам нужен только 128-битный дайджест, вы можете сделать .digest()[:16].

Это даст вам список кортежей, каждый из которых содержит имя файла и его хэш.

И снова я сильно сомневаюсь в том, что вы используете MD5. Вы должны использовать как минимум SHA1, а учитывая недавние недостатки, обнаруженные в SHA1, возможно, даже не это. Некоторые люди считают, что если вы не используете MD5 в "криптографических" целях, то все в порядке. Но вещи имеют тенденцию оказываться шире, чем вы изначально ожидаете, и ваш случайный анализ уязвимостей может оказаться совершенно ошибочным. Лучше всего просто взять за привычку использовать правильный алгоритм с самого начала. Это просто набирать разные буквы. Это не так уж сложно.

Вот более сложный, но экономичный по памяти способ:

import hashlib

def hash_bytestr_iter(bytesiter, hasher, ashexstr=False):
    for block in bytesiter:
        hasher.update(block)
    return hasher.hexdigest() if ashexstr else hasher.digest()

def file_as_blockiter(afile, blocksize=65536):
    with afile:
        block = afile.read(blocksize)
        while len(block) > 0:
            yield block
            block = afile.read(blocksize)


[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.md5()))
    for fname in fnamelst]

И, опять же, поскольку MD5 сломан и не должен больше использоваться:

[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
    for fname in fnamelst]

Опять же, вы можете поставить [:16] после вызова hash_bytestr_iter(...), если вам нужен только 128-битный дайджест.

292
ответ дан 23 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

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