Here are some calculations:
Code: Select all
calculate the CRC-32 hash for hex '01':
inputs:
dividend: binary for hex '01': 0b00000001 = 0x01 = 1
polynomial: 0b100000100110000010001110110110111 = 0x104C11DB7
0b00000001 = 0x01
reverse bits in each byte:
0b10000000 = 0x80
append 32 0 bits:
0b1000000000000000000000000000000000000000 = 0x8000000000
XOR the first 4 bytes with 0xFFFFFFFF:
0b0111111111111111111111111111111100000000 = 0x7FFFFFFF00
'CRC division':
0111111111111111111111111111111100000000
100000100110000010001110110110111 = poly (1)
---------------------------------
111110110011111011100010010010110 = 'bits above poly (1)' ^ poly
100000100110000010001110110110111 = poly (2)
---------------------------------
111100101011110011011001001000010 = 'bits above poly (2)' ^ poly
100000100110000010001110110110111 = poly (3)
---------------------------------
111000011011100010101111111101010 = 'bits above poly (3)' ^ poly
100000100110000010001110110110111 = poly (4)
---------------------------------
110001111011000001000010010111010 = 'bits above poly (4)' ^ poly
100000100110000010001110110110111 = poly (5)
---------------------------------
100010111010000110011001000011010 = 'bits above poly (5)' ^ poly
100000100110000010001110110110111 = poly (6)
---------------------------------
100111000001000101111101011010 = 'bits above poly (6)' ^ poly = remainder
remainder: 0b00100111000001000101111101011010 = 0x27045F5A
XOR the remainder with 0xFFFFFFFF:
0b11011000111110111010000010100101 = 0xD8FBA0A5
reverse bits:
0b10100101000001011101111100011011 = 0xA505DF1B
thus the CRC-32 hash for hex '01' is 0xA505DF1B
I cite various sources in my tutorial, however, I did not come across any official sources.
Here is some code to do the calculations by hand: [EDIT: See improved code underneath.]
Code: Select all
q:: ;calculate CRC-32 hashes by hand
vBin := "0111111111111111111111111111111100000000"
vPoly := "100000100110000010001110110110111"
vLenPoly := StrLen(vPoly)
vOutput := ""
Loop
{
vBin := LTrim(vBin, "0")
if (StrLen(vBin) < vLenPoly)
break
vTemp1 := SubStr(vBin, 1, vLenPoly)
vTemp2 := SubStr(vBin, vLenPoly+1)
vTemp1X := JEE_BinXor(vTemp1, vPoly)
vBin := vTemp1X vTemp2
vOutput .= vTemp1X " " vTemp2 " " JEE_BinToHex(vTemp1X) "`r`n"
}
vBin := LTrim(vBin, "0")
vOutput .= "`r`n" vBin " " JEE_BinToHex(vBin)
vBin := JEE_BinXor(vBin, "11111111111111111111111111111111") ;0xFFFFFFFF
vOutput .= "`r`n" vBin " " JEE_BinToHex(vBin)
vBin := JEE_StrReverse(vBin)
vOutput .= "`r`n" vBin " " JEE_BinToHex(vBin)
Clipboard := vOutput "`r`n"
MsgBox, % "done"
return
JEE_BinXor(vBin1, vBin2)
{
local
vLen := Max(StrLen(vBin1), StrLen(vBin2))
vBin1 := Format("{:0" vLen "}", vBin1)
vBin2 := Format("{:0" vLen "}", vBin2)
vOutput := ""
Loop, % vLen
vOutput .= !(SubStr(vBin1, A_Index, 1) = SubStr(vBin2, A_Index, 1))
;MsgBox, % vBin1 "`r`n" vBin2 "`r`n" vOutput
return vOutput
}
;JEE_Bin2Hex
JEE_BinToHex(vBin)
{
local
vIndex := StrLen(vBin)
;bin2dec
vOutput := 0
Loop, Parse, vBin
{
vIndex--
vOutput += A_LoopField * (2**vIndex)
}
;dec2hex
return Format("{:X}", vOutput)
}
JEE_StrReverse(vText)
{
local
vLen := StrLen(vText)
vOutput := ""
VarSetCapacity(vOutput, vLen*2)
Loop, % vLen
vOutput .= SubStr(vText, vLen-A_Index+1, 1)
;vOutput .= SubStr(vText, vLen--, 1) ;could use
return vOutput
}
[EDIT:] Here is some improved code to do the calculations by hand:
Code: Select all
q:: ;calculate CRC-32 hashes by hand
vBin := "00000001"
vPoly := "100000100110000010001110110110111"
vOutput := vBin "`r`n"
vTemp := vBin, vBin := ""
Loop, % Ceil(StrLen(vTemp/8))
vBin .= JEE_StrReverse(SubStr(vTemp, A_Index*8-7, 8))
vOutput .= vBin "`r`n"
vBin .= Format("{:032}", 0)
vOutput .= vBin "`r`n"
vTemp1 := SubStr(vBin, 1, 32)
vTemp2 := SubStr(vBin, 33)
vBin := JEE_BinXor(vTemp1, "11111111111111111111111111111111") vTemp2 ;0xFFFFFFFF
vOutput .= vBin "`r`n`r`n"
vOutput .= vBin "`r`n"
vLenPoly := StrLen(vPoly)
vBarrier := ""
Loop, % vLenPoly
vBarrier .= "-"
vIndent := ""
Loop, % InStr(vBin, "1") - 1
vIndent .= " "
vBin := LTrim(vBin, "0")
vOutput .= vIndent vPoly "`r`n" vIndent vBarrier "`r`n"
Loop
{
vTemp1 := SubStr(vBin, 1, vLenPoly)
vTemp2 := SubStr(vBin, vLenPoly+1)
vTemp1X := JEE_BinXor(vTemp1, vPoly)
vBin := vTemp1X vTemp2
Loop, % InStr(vBin, "1") - 1
vIndent .= " "
vBin := LTrim(vBin, "0")
if (StrLen(vBin) < vLenPoly)
break
vOutput .= vIndent SubStr(vBin, 1, vLenPoly) "`r`n" vIndent vPoly "`r`n" vIndent vBarrier "`r`n"
}
vOutput .= vIndent SubStr(vBin, 1, vLenPoly) "`r`n"
vBin := LTrim(vBin, "0")
vBin := Format("{:032}", vBin)
vOutput .= "`r`n" vBin " " JEE_BinToHex(vBin)
vBin := JEE_BinXor(vBin, "11111111111111111111111111111111") ;0xFFFFFFFF
vOutput .= "`r`n" vBin " " JEE_BinToHex(vBin)
vBin := JEE_StrReverse(vBin)
vOutput .= "`r`n" vBin " " JEE_BinToHex(vBin)
Clipboard := vOutput "`r`n"
MsgBox, % "done"
return
JEE_BinXor(vBin1, vBin2)
{
local
vLen := Max(StrLen(vBin1), StrLen(vBin2))
vBin1 := Format("{:0" vLen "}", vBin1)
vBin2 := Format("{:0" vLen "}", vBin2)
vOutput := ""
Loop, % vLen
vOutput .= !(SubStr(vBin1, A_Index, 1) = SubStr(vBin2, A_Index, 1))
;MsgBox, % vBin1 "`r`n" vBin2 "`r`n" vOutput
return vOutput
}
;JEE_Bin2Hex
JEE_BinToHex(vBin)
{
local
vIndex := StrLen(vBin)
;bin2dec
vOutput := 0
Loop, Parse, vBin
{
vIndex--
vOutput += A_LoopField * (2**vIndex)
}
;dec2hex
return Format("{:X}", vOutput)
}
JEE_StrReverse(vText)
{
local
vLen := StrLen(vText)
vOutput := ""
VarSetCapacity(vOutput, vLen*2)
Loop, % vLen
vOutput .= SubStr(vText, vLen-A_Index+1, 1)
;vOutput .= SubStr(vText, vLen--, 1) ;could use
return vOutput
}