turns-00065.parquet:33422
c98ec481367a1b911ee47232
turn 1/1gpt-4o-mini-2024-07-18RussianRussia917 words
degenerate_repetitionAbsentFinal dense release
USER
Реализовать 2 консольные проргаммы
Первая программа
Реализовать консольную ПРОГРАММУ на любом языке программирования, которая создаёт JSON файл, в котором записана вся структура ПАПКИ.
Интерфейс: [-h alg] path
-h alg - выполнять хэширование файлов с помощью функции alg (нужно поддержать хотя бы одно из значений alg, равное md5, sha256, sha512, gost256 или gost512), если не указано, то хэширование не выполняется
Если не указано ни одного аргумента, то выводится сообщение помощник, в котором указывается интерфейс программы и описание ключей.
Вывод идёт в стандартный поток вывода. Любые сообщения, отличающиеся от выходного JSON объекта, записываются в поток вывода ошибок.
Описание формата выходного JSON объекта:
В файле записан только один JSON объект ИНФОРМАЦИЯ
Объект ИНФОРМАЦИЯ состоит из следующих полей:
path - строка, указывает абсолютный путь к папке, которую сравнивали
startDate - строка, время запуска сканирования в формате "YYYY-MM-DD hh:mm:dd" (2024-01-01 12:30:00)
finishDate - строка, время окончания сканирования в формате "YYYY-MM-DD hh:mm:dd" (2024-01-01 12:30:00)
scan - массив ПАПКА если по пути path находится папка или объект ФАЙЛ если по пути path находится файл, если происходит какая-то ошибка, то просто строка с текстом ошибки
hash - (отсутствует если не указан ключ -h) название хэш-функции если используется.
ПАПКА является JSON объектом, с полями:
type - имеет значение "dir"
entries - JSON объект, в котором ключом являются имена файлов внутри данной ПАПКИ, а значение - либо ФАЙЛ, либо ПАПКА:
ФАЙЛ является JSON объектом с полями:
type - имеет значение "file"
modt - время последнего изменения файла:
hash - хэш файла в шестнадцатеричном формате
size - размер файла в байтах
Пример запуска:
./scan /home/user/data -h md5
Пример вывода:
{
"path": "/home/user/data",
"hash": "md5",
"scan": {
"a.sh": { "type": "file", "size": 145, "modt": "2023-12-01 12:00:07", hash: "fa12312519abccef99" },
"folder": { "type": "dir", "entries": {
"y.tar.gz": { "type": "file", "size": 80017, "modt": "2021-07-05 12:00:07", hash: "2a1с312559abccef93" }
}}
},
"startDate": "2024-02-06 13:00:00",
"finishDate": "2024-02-06 13:00:17",
}
Вторая программа
Пример запуска: compare file1 file2.
То есть на вход подаётся 2 файла, полученных в качестве результата первой программы. Если какой-то из файлов не существует, то программа должна писать сообщение в стандартный поток вывода ошибок и завершаться с ненулевым кодом.
В результат выводится JSON объект, в котором есть 3 ключа "modified", "deleted" и "created", которые являются массивами. В массивах хранятся пути к соответствующим файлам. Считается состояние папки в файле file2 по сравнению с состоянием папки в файле file1.
{
"modified": [
"path/to/file1",
"path/to/file2"
],
"created": [
"path/to/file3",
"path/to/4"
],
"deleted": [
"path/file5",
"file6"
]
}ASSISTANT
Ниже представлены две консольные программы, соответствующие вашим требованиям. Первая программа создает JSON-файл, представляющий структуру папки, а вторая программа сравнивает два таких файла и выводит изменения.
### Первая программа: `scan.py`
```python
import os
import json
import hashlib
import sys
from datetime import datetime
def hash_file(filepath, algorithm):
hash_func = None
if algorithm == 'md5':
hash_func = hashlib.md5()
elif algorithm == 'sha256':
hash_func = hashlib.sha256()
elif algorithm == 'sha512':
hash_func = hashlib.sha512()
elif algorithm == 'gost256':
hash_func = hashlib.new('gost-crypto', usedigest='256')
elif algorithm == 'gost512':
hash_func = hashlib.new('gost-crypto', usedigest='512')
with open(filepath, 'rb') as f:
while chunk := f.read(8192):
hash_func.update(chunk)
return hash_func.hexdigest()
def scan_directory(path, algorithm):
scanned_data = {}
try:
if not os.path.exists(path):
raise Exception(f"Path {path} does not exist")
scanned_data["path"] = os.path.abspath(path)
scanned_data["startDate"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
entries = {}
for entry in os.listdir(path):
entry_path = os.path.join(path, entry)
if os.path.isdir(entry_path):
entries[entry] = {"type": "dir", "entries": scan_directory(entry_path, algorithm)}
else:
file_info = {
"type": "file",
"size": os.path.getsize(entry_path),
"modt": datetime.fromtimestamp(os.path.getmtime(entry_path)).strftime("%Y-%m-%d %H:%M:%S")
}
if algorithm:
file_info["hash"] = hash_file(entry_path, algorithm)
entries[entry] = file_info
scanned_data["scan"] = entries
scanned_data["finishDate"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if algorithm:
scanned_data["hash"] = algorithm
except Exception as e:
scanned_data = str(e)
return scanned_data
def main():
if len(sys.argv) < 2:
print("Usage: [-h alg] path")
print("alg: md5, sha256, sha512, gost256, gost512")
return
algorithm = None
if sys.argv[1] == '-h' and len(sys.argv) > 2:
algorithm = sys.argv[2]
path = sys.argv[3]
else:
path = sys.argv[1]
result = scan_directory(path, algorithm)
if isinstance(result, dict):
print(json.dumps(result, indent=4))
else:
print(result, file=sys.stderr)
if __name__ == "__main__":
main()
```
### Вторая программа: `compare.py`
```python
import json
import sys
import os
def load_json_file(filename):
with open(filename, 'r') as f:
return json.load(f)
def compare_files(file1, file2):
data1 = load_json_file(file1)
data2 = load_json_file(file2)
modified = []
deleted = []
created = []
entries1 = data1['scan']
entries2 = data2['scan']
all_files1 = {k: v for k, v in entries1.items() if v['type'] == 'file'}
all_files2 = {k: v for k, v in entries2.items() if v['type'] == 'file'}
# Compare for modified and created
for filename, info2 in all_files2.items():
if filename not in all_files1:
created.append(os.path.join(data2['path'], filename))
else:
info1 = all_files1[filename]
if info1["hash"] != info2["hash"]:
modified.append(os.path.join(data2['path'], filename))
# Compare for deleted
for filename in all_files1.keys():
if filename not in all_files2:
deleted.append(os.path.join(data1['path'], filename))
return {
"modified": modified,
"deleted": deleted,
"created": created
}
def main():
if len(sys.argv) != 3:
print("Usage: compare <file1> <file2>", file=sys.stderr)
sys.exit(1)
file1, file2 = sys.argv[1], sys.argv[2]
if not os.path.exists(file1):
print(f"{file1} does not exist", file=sys.stderr)
sys.exit(1)
if not os.path.exists(file2):
print(f"{file2} does not exist", file=sys.stderr)
sys.exit(1)
result = compare_files(file1, file2)
print(json.dumps(result, indent=4))
if __name__ == "__main__":
main()
```
### Как использовать программы
1. **Первая программа** `scan.py`:
- Сканирует указанную папку и выводит структуру в формате JSON.
- Пример запуска:
```bash
python scan.py /path/to/directory -h md5
```
2. **Вторая программа** `compare.py`:
- Сравнивает две JSON-структуры, полученные от первой программы.
- Пример запуска:
```bash
python compare.py file1.json file2.json
```
### Заметки
- Убедитесь, что у вас установлены все необходимые библиотеки для работы с хэшами, если используете специфические алгоритмы.
- Для использования GOST-хэширования может потребоваться сторонняя библиотека (например, `gost-crypto`), которая не всегда доступна в системах по умолчанию. Вы можете заменить его на другой доступный алгоритм хэширования.
- Обработка ошибок в обеих программах направлена на предоставление понятных сообщений в стандартный поток ошибок.