Calculating checksums are perhaps not the first thing you would think of needing to do in PowerShell. But if you ever are in a situation that you need to calculate a checksum using the CRC32 algorithm, I got you covered with this small function.
I can’t take full credit for the code itself, all I did was converting the code from C to PowerShell.
Example
[System.Text.Encoding]::ASCII.GetBytes("PowerShell") | Get-CRC32
This will give you the CRC32 checksum of 2730794414, which is an INT64. If you want to convert it to HEX, you can do the following:
[System.Convert]::ToString(2730794414,16)
This will give you the HEX value of a2c49dae.
The function takes a byte array as input, which is the reason I had to convert the string in the example above.
Here is the function it self, with another example included:
| function Get-CRC32 { | |
| <# | |
| .SYNOPSIS | |
| Calculate CRC. | |
| .DESCRIPTION | |
| This function calculates the CRC of the input data using the CRC32 algorithm. | |
| .EXAMPLE | |
| Get-CRC32 $data | |
| .EXAMPLE | |
| $data | Get-CRC32 | |
| .NOTES | |
| C to PowerShell conversion based on code in https://www.w3.org/TR/PNG/#D-CRCAppendix | |
| Author: Øyvind Kallstad | |
| Date: 06.02.2017 | |
| Version: 1.0 | |
| .INPUTS | |
| byte[] | |
| .OUTPUTS | |
| uint32 | |
| .LINK | |
| https://communary.net/ | |
| .LINK | |
| https://www.w3.org/TR/PNG/#D-CRCAppendix | |
| #> | |
| [CmdletBinding()] | |
| param ( | |
| # Array of Bytes to use for CRC calculation | |
| [Parameter(Position = 0, ValueFromPipeline = $true)] | |
| [ValidateNotNullOrEmpty()] | |
| [byte[]]$InputObject | |
| ) | |
| Begin { | |
| function New-CrcTable { | |
| [uint32]$c = $null | |
| $crcTable = New-Object 'System.Uint32[]' 256 | |
| for ($n = 0; $n -lt 256; $n++) { | |
| $c = [uint32]$n | |
| for ($k = 0; $k -lt 8; $k++) { | |
| if ($c -band 1) { | |
| $c = (0xEDB88320 -bxor ($c -shr 1)) | |
| } | |
| else { | |
| $c = ($c -shr 1) | |
| } | |
| } | |
| $crcTable[$n] = $c | |
| } | |
| Write-Output $crcTable | |
| } | |
| function Update-Crc ([uint32]$crc, [byte[]]$buffer, [int]$length) { | |
| [uint32]$c = $crc | |
| if (-not($script:crcTable)) { | |
| $script:crcTable = New-CrcTable | |
| } | |
| for ($n = 0; $n -lt $length; $n++) { | |
| $c = ($script:crcTable[($c -bxor $buffer[$n]) -band 0xFF]) -bxor ($c -shr 8) | |
| } | |
| Write-output $c | |
| } | |
| $dataArray = @() | |
| } | |
| Process { | |
| foreach ($item in $InputObject) { | |
| $dataArray += $item | |
| } | |
| } | |
| End { | |
| $inputLength = $dataArray.Length | |
| Write-Output ((Update-Crc -crc 0xffffffffL -buffer $dataArray -length $inputLength) -bxor 0xffffffffL) | |
| } | |
| } | |
| [byte[]]$testCrc = 44,6,119,207 | |
| [byte[]]$testData = 73,72,68,82,0,0,0,32,0,0,0,32,1,0,0,0,1 | |
| # should be the same | |
| [array]::Reverse($testCrc) | |
| [System.BitConverter]::ToUInt32($testCrc,0) | |
| Get-CRC32 $testData |
This seems to generate crc32B and not crc32.
LikeLiked by 1 person
No zeros at the beginning of hex CRC, you need to add them manually.
LikeLike