Решил окончательно добить тему контрольных сумм в PowerShell. Предыдущий пост был здесь. Полноценная считалка лежит здесь.
Не так давно столкнулся с потоковым подсчётом контрольных сумм для кучи текстовых файлов. Важным условием было создание файла формата .md5, в котором должна храниться эталонная контрольная сумма и имя исследуемого файла. Само собой, применение каких-либо сторонних утилит я не рассматривал.
В файле .md5 хранится хэш и имя файла, с которого этот хэш и считался. Структура файла выглядит так: hash *filename.ext. Его можно открыть любым текстовым редактором и посмотреть, как саму контрольную сумму, так и целевой файл.
Для реализации поставленной задачи я написал вот такую функцию на базе командлета Get-FileHash:
function SaveMD5 ($path)
{
if (Test-Path -Path $path)
{
try
{
$filename = (Get-Item $path).Name
$dirname = (Get-Item $path).DirectoryName
$woext = (Get-Item $path).BaseName
$content = (Get-FileHash -Path $path -Algorithm MD5).Hash + " *" + $filename
$content | Out-File $dirname\$woext".md5" -NoNewline -ErrorAction Stop
}
catch { $errorsave = "Ошибка сохранения файла!"; return $errorsave }
}
else { $errorfile = "Файл не найден!"; return $errorfile }
}
Функция проверяет наличие файла, считает его контрольную сумму и создает файл .md5. При возникновении ошибки возвращает переменные $errorsave или $errorfile.
Использовать функцию можно так:
SaveMD5 -path "P:\ATH\TO\FI.LE"
Для массовой обработки файлов запихнул функцию в цикл foreach:
$files = Get-ChildItem -Path D:\downloads\test
foreach ($file in $files) { SaveMD5 -path $file.FullName }
Разумеется, лучше избегать пробелов в именах файлов.
А теперь предположим, что имеется файл и документ .md5 с его контрольной суммой. Нужно проверить совпадает ли контрольная сумма из документа с контрольной суммой самого файла. Для этих целей я подготовил обратную функцию:
function CheckMD5 ($md5file)
{
if (Test-Path -Path $md5file)
{
$dirname = (Get-Item $md5file).DirectoryName
$content = (Get-Content -Path $md5file).Split(" *", [StringSplitOptions]::RemoveEmptyEntries)
$md5hash = $content[0]
$filename = $content[1]
$pathtofile = $dirname + "\" + $filename
$gethash = (Get-FileHash -Path $pathtofile -Algorithm MD5).Hash
if ($md5hash -eq $gethash) { return $true } else { return $false }
}
else { $errorfile = "Файл не найден!"; return $errorfile }
}
Функция CheckMD5 парсит файл .md5 и создаёт массив из двух строк. Первая строка ($content[0]) содержит контрольную сумму, а вторая ($content[1]) имя файла. Далее идёт повторное вычисление контрольной суммы файла из $content[1] и сравнивание полученного хэша с $content[0].
Если всё совпадает возвращается True, а если нет — False.
Обращение к функции выглядит так:
CheckMD5 -md5file "P:\ATH\TO\FILE.MD5"
И последний штрих — это цикл:
$files = (Get-ChildItem -Path D:\downloads\test -Filter *.md5).FullName
foreach ($file in $files) { $func=CheckMD5 -md5file $file; Write-Host $file - $func }
Ну, и напоследок пример для экспресс-подсчёта контрольной суммы файла:
$filename = Get-Clipboard -Format FileDropList (Get-FileHash -Path $filename -Algorithm MD5).Hash | Set-Clipboard
Помещаете файл в буфер обмена и запускаете эту конструкцию. По итогу в буфер вернётся контрольная сумма скопированного файла. Можно создать скрипт .ps1 и запускать его при необходимости.