确认两个文件是否完全相同 —— 在 PowerShell 中使用 SHA-256

PowerShellカテゴリを表すパンダのイラスト PowerShell

关于本文
本文是基于 Microsoft Learn 和 NIST 的公开资料整理编写的。

验证状态:📘 已确认官方规范·Windows 实机未验证
所附代码适用于 PowerShell。由于未经实机验证,故未标注“已复制并执行验证”。

如果您想确认两个文件的内容是否相同,最清晰的方法是使用 PowerShell 的 Get-FileHash 计算 SHA-256,然后比较它们的哈希值。您可以比较从内容计算出的值,而不是文件名或修改时间。

最小比较

$hashA = (Get-FileHash -LiteralPath '.fileA.bin' -Algorithm SHA256).Hash
$hashB = (Get-FileHash -LiteralPath '.fileB.bin' -Algorithm SHA256).Hash

$hashA -eq $hashB

若为 True,则表示 SHA-256 一致;若为 False,则表示不一致。

flowchart LR
    A[File A] --> C[SHA-256]
    B[File B] --> D[SHA-256]
    C --> E{Digestを比較}
    D --> E
    E -->|一致| F[同一内容の確認に使う]
    E -->|不一致| G[内容は異なる]

根据 Microsoft Learn,Get-FileHash 的默认算法是 SHA256。

创建虚拟文件进行验证

Set-Content -LiteralPath '.fileA.txt' -Value 'papanda925 sample' -NoNewline
Copy-Item -LiteralPath '.fileA.txt' -Destination '.fileB.txt'

Get-FileHash -LiteralPath '.fileA.txt' -Algorithm SHA256
Get-FileHash -LiteralPath '.fileB.txt' -Algorithm SHA256

由于 fileB 是 fileA 的副本,如果内容没有改变,哈希值也会一致。

接下来,只更改一个字符。

Set-Content -LiteralPath '.fileB.txt' -Value 'papanda925 Sample' -NoNewline

(Get-FileHash '.fileA.txt').Hash
(Get-FileHash '.fileB.txt').Hash

只需对输入做一点微小的改变,哈希值就会发生巨大的变化。

flowchart TB
    A["papanda925 sample"] --> B[SHA-256]
    C["papanda925 Sample"] --> D[SHA-256]
    B --> E[Digest A]
    D --> F[Digest B]
    E -. 入力が1文字違う .-> F

大小相同并不意味着内容相同

下面两个文件的长度相同,但内容不同。

ABCDEF
123456

文件大小对于“快速找出明显不同的文件”很有用,但它不能替代内容比较。

在实际代码中加入存在性检查

$pathA = '.fileA.txt'
$pathB = '.fileB.txt'

foreach ($path in @($pathA, $pathB)) {
    if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
        throw "File not found: $path"
    }
}

$a = Get-FileHash -LiteralPath $pathA -Algorithm SHA256
$b = Get-FileHash -LiteralPath $pathB -Algorithm SHA256

[pscustomobject]@{
    FileA = $a.Path
    FileB = $b.Path
    HashA = $a.Hash
    HashB = $b.Hash
    Same  = ($a.Hash -eq $b.Hash)
}

为了避免“比较了不存在的文件,但后续处理看起来成功了”这种情况,请先检查输入。

也可用于验证下载的文件

如果分发方公开了 SHA-256 值,您可以将其与您下载的文件值进行比较。

Get-FileHash -LiteralPath '.download.iso' -Algorithm SHA256

关键不仅在于比较“自己计算出的两个值”,还在于将其与可信分发方通过其他途径公开的预期值进行核对。

SHA-256 与碰撞(collision)

密码学哈希中存在碰撞(collision)的概念,即不同的输入产生相同的值。因此,从数学意义上严格解释“哈希相同则绝对相同”是不严谨的。

另一方面,SHA-256 在常规的文件完整性检查中被广泛使用。Microsoft Learn 也将 Get-FileHash 的默认值设为 SHA256,并解释说 MD5 和 SHA1 已不再被认为能够抵御攻击。

哈希不是加密

SHA-256 并不是一种对文件进行保密处理的机制。

flowchart LR
    A[ファイル内容] --> B[SHA-256]
    B --> C[固定長のdigest]
    C -. 元ファイルを暗号化しているわけではない .-> D[秘密保持とは別]

完整性验证和加密的目的截然不同。

总结

  • 可以使用 Get-FileHash 根据文件内容计算 SHA-256

  • 比单纯依赖文件名、日期和大小更适合进行内容比较

  • 哪怕只修改一个字符,哈希值也会发生变化

  • 也可用于与分发方公开的 SHA-256 进行核对

  • SHA-256 不是用于保密的加密技术

官方信息与一手资料

Microsoft Learn — Get-FileHash
https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/get-filehash

NIST — Secure Hash Standard (SHS)
https://csrc.nist.gov/pubs/fips/180-4/upd1/final

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

标题和URL已复制