Guest User

Untitled

a guest
Aug 19th, 2025
8
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.98 KB | Source Code | 0 0
  1. import os
  2. import hashlib
  3. import platform
  4. import concurrent.futures
  5. from concurrent.futures import ProcessPoolExecutor, as_completed
  6. from tqdm import tqdm
  7.  
  8. def compute_hash(filepath, algorithm):
  9. """Вычисляет хеш файла с использованием указанного алгоритма."""
  10. try:
  11. hash_obj = hashlib.new(algorithm)
  12. with open(filepath, 'rb') as f:
  13. while chunk := f.read(4096 * 16):
  14. hash_obj.update(chunk)
  15. return {'status': 'success', 'hash': hash_obj.hexdigest(), 'path': filepath}
  16. except Exception as e:
  17. return {'status': 'error', 'path': filepath, 'message': str(e)}
  18.  
  19. def normalize_path(path):
  20. """Обработка длинных путей для Windows."""
  21. if platform.system() == 'Windows':
  22. path = os.path.abspath(path)
  23. if len(path) > 260 and not path.startswith('\\\\?\\'):
  24. return '\\\\?\\' + path
  25. return os.path.abspath(path)
  26.  
  27. def get_files(path):
  28. """Рекурсивный поиск файлов с обработкой специальных символов."""
  29. try:
  30. path = normalize_path(path)
  31. if os.path.isfile(path):
  32. return [path]
  33.  
  34. file_list = []
  35. for root, _, files in os.walk(path):
  36. for file in files:
  37. full_path = os.path.join(root, file)
  38. file_list.append(normalize_path(full_path))
  39. return file_list
  40. except Exception as e:
  41. raise ValueError(f"Ошибка обхода каталога: {str(e)}")
  42.  
  43. def process_batch(files, algorithm):
  44. """Обработка пакета файлов в отдельном процессе."""
  45. return [compute_hash(f, algorithm) for f in files]
  46.  
  47. def main():
  48. # Ввод параметров
  49. scan_path = input("1) Укажите путь для сканирования: ").strip()
  50. if not os.path.exists(scan_path):
  51. print("Ошибка: Указанный путь не существует")
  52. return
  53.  
  54. algorithms = ['sha256', 'sha3-256', 'blake2s', 'md5']
  55. print("\n2) Выберите алгоритм хеширования:")
  56. for i, alg in enumerate(algorithms, 1):
  57. print(f"{i}. {alg}")
  58.  
  59. try:
  60. choice = int(input("Номер алгоритма: ")) - 1
  61. algorithm = algorithms[choice].replace('-', '_')
  62. except (ValueError, IndexError):
  63. print("Ошибка: Некорректный выбор алгоритма")
  64. return
  65.  
  66. save_dir = input("\n3) Путь для сохранения результатов: ").strip()
  67. if not os.path.isdir(save_dir):
  68. print("Ошибка: Каталог для сохранения не существует")
  69. return
  70.  
  71. # Получение списка файлов
  72. try:
  73. files = get_files(scan_path)
  74. if not files:
  75. print("Нет файлов для обработки")
  76. return
  77. except Exception as e:
  78. print(f"Ошибка: {str(e)}")
  79. return
  80.  
  81. # Настройка многопроцессорности
  82. cpu_count = os.cpu_count() or 4
  83. batch_size = max(len(files) // (cpu_count * 4), 1)
  84. batches = [files[i:i+batch_size] for i in range(0, len(files), batch_size)]
  85.  
  86. # Инициализация файлов результатов
  87. save_path = os.path.join(save_dir, f"checksums.{algorithms[choice]}")
  88. error_log_path = os.path.join(save_dir, "hash_errors.log")
  89.  
  90. stats = {
  91. 'total': len(files),
  92. 'processed': 0,
  93. 'errors': 0,
  94. 'error_list': []
  95. }
  96.  
  97. with ProcessPoolExecutor(max_workers=cpu_count) as executor, \
  98. open(save_path, 'w', encoding='utf-8') as output_file, \
  99. tqdm(total=stats['total'], desc="Обработка файлов", unit="file") as pbar:
  100.  
  101. # Запуск задач обработки
  102. futures = [executor.submit(process_batch, batch, algorithm) for batch in batches]
  103.  
  104. # Обработка результатов
  105. for future in as_completed(futures):
  106. try:
  107. results = future.result()
  108. for result in results:
  109. if result['status'] == 'success':
  110. output_file.write(f"{result['hash']} {result['path']}\n")
  111. stats['processed'] += 1
  112. else:
  113. stats['error_list'].append(result)
  114. stats['errors'] += 1
  115. pbar.update(1)
  116. except Exception as e:
  117. print(f"\nОшибка обработки пакета: {str(e)}")
  118.  
  119. # Запись лога ошибок
  120. if stats['error_list']:
  121. with open(error_log_path, 'w', encoding='utf-8') as err_file:
  122. err_file.write("Список ошибок при обработке файлов:\n\n")
  123. for error in stats['error_list']:
  124. err_file.write(f"Файл: {error['path']}\nОшибка: {error['message']}\n\n")
  125.  
  126. # Формирование отчета
  127. print("\n" + "=" * 50)
  128. print(f"Итоговый отчет:")
  129. print(f"Всего файлов: {stats['total']}")
  130. print(f"Успешно обработано: {stats['processed']}")
  131. print(f"Файлов с ошибками: {stats['errors']}")
  132.  
  133. if stats['error_list']:
  134. print(f"\nСписок ошибок сохранен в: {error_log_path}")
  135. print("Первые 5 ошибок:")
  136. for error in stats['error_list'][:5]:
  137. print(f"• {error['path']}\n → {error['message']}")
  138.  
  139. print(f"\nФайл с хеш-суммами: {save_path}")
  140. print("=" * 50)
  141.  
  142. # Пауза перед завершением
  143. if platform.system() == 'Windows':
  144. os.system('pause')
  145. else:
  146. input("\nНажмите Enter для выхода...")
  147.  
  148. if __name__ == "__main__":
  149. main()
Add Comment
Please, Sign In to add comment