Private/Get-KadenFileDigest.ps1

function Get-KadenFileDigest {
    <#
    .SYNOPSIS
        Return the lowercase SHA-256 digest of a file after LF newline normalization.
    .DESCRIPTION
        CRLF and lone CR are treated as LF before hashing so Windows working trees
        and Linux Gallery checkouts agree with digests written by the packer.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$LiteralPath
    )

    $raw = [System.IO.File]::ReadAllBytes($LiteralPath)
    $out = New-Object System.Collections.Generic.List[byte]
    for ($i = 0; $i -lt $raw.Length; $i++) {
        $b = $raw[$i]
        if ($b -eq 13) {
            if (($i + 1) -lt $raw.Length -and $raw[$i + 1] -eq 10) {
                continue
            }
            $out.Add([byte]10)
            continue
        }
        $out.Add($b)
    }
    $normalized = $out.ToArray()
    $sha = [System.Security.Cryptography.SHA256]::Create()
    try {
        $hash = $sha.ComputeHash($normalized)
        return ([System.BitConverter]::ToString($hash) -replace '-', '').ToLowerInvariant()
    }
    finally {
        $sha.Dispose()
    }
}