Почему хэш учитывает одно и то же значение для каждого нового временного файла, созданного для входного файла в вызове API? - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть вызов API, который берет файл ввода из формы и генерирует ключ хеша для созданного временного файла. Но опять же, когда в качестве входного файла выбирается другой файл, генерируется тот же хэш. Ниже приведен фрагмент кода вызова API: (исключая другой не связанный код)

 def gen_hash():
     for attr, document in request.files.iteritems():
            orig_filename = document.filename
            new_doc = add_doc(orig_filename, orig_filename)
            #mhash = None
            ##############
            # hashing algorithm checks the contents of the file if
            # modified before uploading to destination, NOT file name
            try:
                tmp1 = tempfile.NamedTemporaryFile(delete=False)
                tmp1.write(document.read())
                tmp1.seek(0)
                # for chunk in iter(lambda: tmp1.read(128* sha1().block_size),
                #                   b""):
                for chunk in iter(lambda: tmp1.read(128), b""):
                    sha1().update(chunk)
                mhash1 = sha1().hexdigest()
                print mhash1
            finally:
                #print e
                os.unlink(tmp1.name) 

Использование колбы v.0.12, python 2.7. Почему хеш-ключ одинаков для разных файлов?

1 Ответ

0 голосов
/ 29 апреля 2018

hashlib.sha1() создает хеш-объект SHA-1, который можно обновить данными и, наконец, получить дайджест. Но вы не сохраняете этот объект. Новый объект создается и отбрасывается для каждого чанка, а затем вы создаете еще один пустой дайджест и принимаете его значение. Вы всегда хешируете одну и ту же пустую последовательность и получаете da39a3ee5e6b4b0d3255bfef95601890afd80709.

Так как вы захватываете весь документ за один read, нет смысла записывать его во временный файл и выполнять фрагментированные чтения. Просто хешируйте данные, которые вы взяли.

def gen_hash():
    for attr, document in request.files.iteritems():
        orig_filename = document.filename
        new_doc = add_doc(orig_filename, orig_filename)
        mhash1 = sha1(document.read()).hexdigest()
        print mhash1

Предполагая, что document представляет собой объект, подобный файлу, вы можете обновить хеш в блоках и избежать затрат памяти на чтение всего документа сразу.

def gen_hash():
    for attr, document in request.files.iteritems():
        orig_filename = document.filename
        new_doc = add_doc(orig_filename, orig_filename)
        hash = sha1()
        for chunk in iter(lambda: document.read(65536), ''):
            hash.update(chunk)
        mhash1 = hash.hexdigest()
        print mhash1

Когда iter вызывается с двумя параметрами, первый - это функция, которая генерирует данные, а второй - конечное условие для итерации. Таким образом, iter(lambda: document.read(65536), '') продолжает вызывать функцию, которая читает данные из document, пока ничего не останется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...