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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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