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