Python hashlib Дайджест MD5 любого файла UNC всегда дает один и тот же хэш

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

Python 2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> fn_a = '\\\\some.host.com\\Shares\\folder1\\file_a'
>>> fn_b = '\\\\some.host.com\\Shares\\folder1\\file_b'
>>> fn_c = '\\\\some.host.com\\Shares\\folder2\\file_c'
>>> fn_d = 'E:\\file_d'
>>> fn_e = 'E:\\file_e'
>>> fn_f = 'E:\\folder3\\file_f'
>>> f_a = open(fn_a, 'r')
>>> f_b = open(fn_b, 'r')
>>> f_c = open(fn_c, 'r')
>>> f_d = open(fn_d, 'r')
>>> f_e = open(fn_e, 'r')
>>> f_f = open(fn_f, 'r')
>>> hashlib.md5(f_a.read()).hexdigest()
'54637fdcade4b7fd7cabd45d51ab8311'
>>> hashlib.md5(f_b.read()).hexdigest()
'54637fdcade4b7fd7cabd45d51ab8311'
>>> hashlib.md5(f_c.read()).hexdigest()
'54637fdcade4b7fd7cabd45d51ab8311'
>>> hashlib.md5(f_d.read()).hexdigest()
'd2bf541b1a9d2fc1a985f65590476856'
>>> hashlib.md5(f_e.read()).hexdigest()
'e84be3c598a098f1af9f2a9d6f806ed5'
>>> hashlib.md5(f_f.read()).hexdigest()
'e11f04ed3534cc4784df3875defa0236'

РЕДАКТИРОВАТЬ: Для дальнейшего изучения проблемы, я также проверил, используя файл с другого хоста. Похоже, что изменение хоста изменит результат.

>>> fn_h = '\\\\host\\share\\file'
>>> f_h = open(fn_h, 'r')
>>> hashlib.md5(f_h.read()).hexdigest()
'f23ee2dbbb0040bf2586cfab29a03634'

... но потом я попробовал другой файл на новом хосте и получил новый результат!

>>> fn_i = '\\\\host\\share\\different_file'
>>> f_i = open(fn_i, 'r')
>>> hashlib.md5(f_i.read()).hexdigest()
'a8ad771db7af8c96f635bcda8fdce961'

Итак, теперь я действительно запутался. Может ли это иметь какое-то отношение к тому факту, что \\host.com формат и новый хост \\host формат?

3 ответа

Решение

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

  1. В качестве имени пути используется необработанный строковый литерал, т.е.
    A. Строка пути к файлу является необработанной с одиночной обратной косой чертой в пути, по сравнению с
    B. Строка пути к файлу не является необработанной с двойной обратной косой чертой в пути

    (К сведению тех, кто не знает, необработанная строка - это та, за которой следует буква "r", например: r'This is a raw string')

  2. open режим работы r или же rb,
    (Снова к тем, кто не знает, b в rb режим указывает на чтение файла в двоичном виде.)

Результаты продемонстрировали:

  • Строковый литерал / обратная косая черта не имеют значения, различаются ли хэши разных файлов
  • Моя ошибка не была открытием файла в двоичном режиме. Когда используешь rb режим в openЯ получил разные результаты.

Ура! И спасибо за помощь.

Использование f1.seek(0) если вы собираетесь использовать его снова, в противном случае это будет файл, полностью прочитанный и вызывающий read() снова просто вернет пустую строку.

Я не воспроизвожу твою проблему. Я использую Python 3.4 в Windows 7 здесь со следующим тестовым скриптом, который обращается к файлам на сетевом жестком диске:

import sys, hashlib
def main():
    fn0 = r'\\NAS\Public\Software\Backup\Test\Vagrantfile'
    fn1 = r'\\NAS\Public\Software\Backup\Test\z.xml'
    with open(fn0, 'rb') as f:
        h0 = hashlib.md5(f.read())
        print(h0.hexdigest())
    with open(fn1, 'rb') as f:
        h1 = hashlib.md5(f.read())
        print(h1.hexdigest())

if __name__ == '__main__':
    sys.exit(main())

Запуск этого приводит к двум различным значениям хеша (как и ожидалось):

c:\src\python>python hashtest.py
8af202dffb88739c2dbe188c12291e3d
2ff3db61ff37ca5ceac6a59fd7c1018b

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

Другие вопросы по тегам