Utils/sum.ps1
|
Register-GnuUtil @{ Name = 'sum' Category = 'Checksums' Synopsis = 'Checksum and count the blocks in a file.' Usage = @('sum [OPTION]... [FILE]...') Description = @('Print or check BSD (16-bit) checksums.', '', 'With no FILE, or when FILE is -, read standard input.') FileOperands = $true Options = @( @{ Short = 'r'; Key = 'algorithm'; Value = 'bsd'; Help = 'use BSD sum algorithm (the default), use 1K blocks' } @{ Short = 's'; Long = 'sysv'; Key = 'algorithm'; Value = 'sysv'; Help = 'use System V sum algorithm, use 512 bytes blocks' } ) } function script:Get-GnuSumLine { <# .SYNOPSIS "CHECKSUM BLOCKS" as printed by sum -r (BSD) or sum -s (System V), without the file name. #> param([Parameter(Mandatory)][AllowEmptyCollection()][byte[]]$Bytes, [switch]$SysV) if ($SysV) { $total = [long]0 foreach ($byte in $Bytes) { $total = ($total + $byte) -band 0xFFFFFFFFL } $folded = ($total -band 0xFFFF) + (($total -shr 16) -band 0xFFFF) return "$(($folded -band 0xFFFF) + ($folded -shr 16)) $([long][Math]::Ceiling($Bytes.Length / 512))" } $checksum = 0 foreach ($byte in $Bytes) { $checksum = (($checksum -shr 1) + (($checksum -band 1) -shl 15) + $byte) -band 0xFFFF } ([string]$checksum).PadLeft(5, '0') + ' ' + ([string][long][Math]::Ceiling($Bytes.Length / 1024)).PadLeft(5) } |