This is my code for CRC calculating. It calculates CRC32 using the standard polynomial 0x04C11DB7, and also 2 different 16bit CRCs (one uses the standard CRC16 polynomial 0x8005, and the other uses the CCITT polynomial 0x1021). Both the CRC32 and CRC16 functions allow the following parameters to be configured that affect the calculation of the CRC:
InvertInitCRC (if true, the initial CRC value has all 1 bits, otherwise it is has all 0 bits)
MirrorInputBits (if true, the bit order in each byte of input data is reversed before being used to calculate the CRC)
MirrorOutputBits (if true, the order of the bits in the output CRC is reversed, which is a 32bit reversal for CRC32 and a 16bit reversal for CRC16)
InvertFinalCRC (if true, the output bits of the CRC are all inverted, where 1 becomes 0, and 0 becomes 1)
These above parameters are all required parameters in both functions. That is, they must be explicitly set to true or false.
Also, both CRC functions have an optional parameter called SwapOutputBytes. This simply affects the "endianness" of the output CRC (the order in which the CRC's bytes are stored in memory or in a file).
The CRC16 function, has an extra required parameter called UsePolyCCITT. If true, it uses the CCITT polynomial (often used in various communications protocols), which is 0x1021. If false, it uses the standard CRC16 polynomial, which is 0x8005.
Note that for the CRC32 function to perform the standard CRC32 calculation, the 4 required parameters must be set as shown here:
InvertInitCRC = True
MirrorInputBits = True
MirrorInputBits = True
InvertFinalCRC = True
Note that for the CRC16 function to perform the standard CRC16 calculation, the 5 required parameters must be set as shown here:
UsePolyCCITT = False
InvertInitCRC = False
MirrorInputBits = True
MirrorInputBits = True
InvertFinalCRC = False
Here's the complete code for this module. Just copy and paste it into a module in VB6, and then you will be able to use the CRC32 and CRC16 functions from anywhere else in your code.
InvertInitCRC (if true, the initial CRC value has all 1 bits, otherwise it is has all 0 bits)
MirrorInputBits (if true, the bit order in each byte of input data is reversed before being used to calculate the CRC)
MirrorOutputBits (if true, the order of the bits in the output CRC is reversed, which is a 32bit reversal for CRC32 and a 16bit reversal for CRC16)
InvertFinalCRC (if true, the output bits of the CRC are all inverted, where 1 becomes 0, and 0 becomes 1)
These above parameters are all required parameters in both functions. That is, they must be explicitly set to true or false.
Also, both CRC functions have an optional parameter called SwapOutputBytes. This simply affects the "endianness" of the output CRC (the order in which the CRC's bytes are stored in memory or in a file).
The CRC16 function, has an extra required parameter called UsePolyCCITT. If true, it uses the CCITT polynomial (often used in various communications protocols), which is 0x1021. If false, it uses the standard CRC16 polynomial, which is 0x8005.
Note that for the CRC32 function to perform the standard CRC32 calculation, the 4 required parameters must be set as shown here:
InvertInitCRC = True
MirrorInputBits = True
MirrorInputBits = True
InvertFinalCRC = True
Note that for the CRC16 function to perform the standard CRC16 calculation, the 5 required parameters must be set as shown here:
UsePolyCCITT = False
InvertInitCRC = False
MirrorInputBits = True
MirrorInputBits = True
InvertFinalCRC = False
Here's the complete code for this module. Just copy and paste it into a module in VB6, and then you will be able to use the CRC32 and CRC16 functions from anywhere else in your code.
Code:
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Public Function CRC32(ByRef Data() As Byte, _
ByVal InvertInitCRC As Boolean, _
ByVal MirrorInputBits As Boolean, _
ByVal MirrorOutputBits As Boolean, _
ByVal InvertFinalCRC As Boolean, _
Optional ByVal SwapOutputBytes As Boolean) As Long
Dim ByteNumber As Long
Dim BitNumber As Long
Dim CurrentByte As Long
Dim CRC As Long
Const Poly As Long = &H4C11DB7
If InvertInitCRC Then CRC = &HFFFFFFFF Else CRC = 0
For ByteNumber = 0 To UBound(Data)
CurrentByte = Data(ByteNumber)
If MirrorInputBits Then CurrentByte = ReverseBits8(CurrentByte)
CurrentByte = SwapBytes4(CurrentByte)
CRC = CRC Xor CurrentByte
For BitNumber = 0 To 7
If CRC And &H80000000 Then
CRC = ShiftLeft32(CRC) Xor Poly
Else
CRC = ShiftLeft32(CRC)
End If
Next BitNumber
Next ByteNumber
If MirrorOutputBits Then CRC = ReverseBits32(CRC)
If InvertFinalCRC Then CRC = CRC Xor &HFFFFFFFF
If SwapOutputBytes Then CRC = SwapBytes4(CRC)
CRC32 = CRC
End Function
Public Function CRC16(ByRef Data() As Byte, _
ByVal UsePolyCCITT As Boolean, _
ByVal InvertInitCRC As Boolean, _
ByVal MirrorInputBits As Boolean, _
ByVal MirrorOutputBits As Boolean, _
ByVal InvertFinalCRC As Boolean, _
Optional ByVal SwapOutputBytes As Boolean) As Integer
Dim ByteNumber As Long
Dim BitNumber As Long
Dim CurrentByte As Long
Dim CRC As Integer
Dim Poly As Integer
Const PolyStandard As Integer = &H8005
Const PolyCCITT As Integer = &H1021
If UsePolyCCITT Then Poly = PolyCCITT Else Poly = PolyStandard
If InvertInitCRC Then CRC = &HFFFF Else CRC = 0
For ByteNumber = 0 To UBound(Data)
CurrentByte = Data(ByteNumber)
If MirrorInputBits Then CurrentByte = ReverseBits8(CurrentByte)
CurrentByte = SwapBytes2(CurrentByte)
CRC = CRC Xor CurrentByte
For BitNumber = 0 To 7
If CRC And &H8000 Then
CRC = ShiftLeft16(CRC) Xor Poly
Else
CRC = ShiftLeft16(CRC)
End If
Next BitNumber
Next ByteNumber
If MirrorOutputBits Then CRC = ReverseBits16(CRC)
If InvertFinalCRC Then CRC = CRC Xor &HFFFF
If SwapOutputBytes Then CRC = SwapBytes2(CRC)
CRC16 = CRC
End Function
Private Function ReverseBits8(ByVal Value As Byte) As Byte
Dim Value2 As Byte
Dim n As Long
Value2 = (Value And 1) * &H80
For n = 1 To 7
Value2 = Value2 + ShiftLeft32(ShiftRight32(Value, n) And 1, 7 - n)
Next n
ReverseBits8 = Value2
End Function
Private Function ShiftLeft32(ByVal Value As Long, Optional ByVal BitCount As Long = 1) As Long
Dim temp As Currency
Dim temp2 As Long
CopyMemory temp, Value, 4
temp = temp * (2 ^ BitCount)
CopyMemory temp2, temp, 4
ShiftLeft32 = temp2
End Function
Private Function ShiftRight32(ByVal Value As Long, Optional ByVal BitCount As Long = 1) As Long
Dim temp As Currency
Dim temp2 As Long
CopyMemory temp, Value, 4
temp = Int((temp * 10000) / (2 ^ BitCount)) / 10000
CopyMemory temp2, temp, 4
ShiftRight32 = temp2
End Function
Private Function ReverseBits32(ByVal Value As Long) As Long
Dim Value2 As Long
Dim n As Long
Value2 = (Value And 1) * &H80000000
For n = 1 To 31
Value2 = Value2 + ShiftLeft32(ShiftRight32(Value, n) And 1, 31 - n)
Next n
ReverseBits32 = Value2
End Function
Private Function SwapBytes4(ByVal Value As Long) As Long
Dim Value2 As Long
CopyMemory ByVal VarPtr(Value2) + 0, ByVal VarPtr(Value) + 3, 1
CopyMemory ByVal VarPtr(Value2) + 1, ByVal VarPtr(Value) + 2, 1
CopyMemory ByVal VarPtr(Value2) + 2, ByVal VarPtr(Value) + 1, 1
CopyMemory ByVal VarPtr(Value2) + 3, ByVal VarPtr(Value) + 0, 1
SwapBytes4 = Value2
End Function
Private Function ShiftRight16(ByVal Value As Integer, Optional ByVal BitCount As Long = 1) As Integer
Dim temp As Long
Dim temp2 As Integer
CopyMemory temp, Value, 2
temp = temp \ (2 ^ BitCount)
CopyMemory temp2, temp, 2
ShiftRight16 = temp2
End Function
Private Function ShiftLeft16(ByVal Value As Integer, Optional ByVal BitCount As Long = 1) As Integer
Dim temp As Long
Dim temp2 As Integer
CopyMemory temp, Value, 2
temp = temp * (2 ^ BitCount)
CopyMemory temp2, temp, 2
ShiftLeft16 = temp2
End Function
Private Function ReverseBits16(ByVal Value As Integer) As Integer
Dim Value2 As Integer
Dim n As Long
Value2 = (Value And 1) * &H8000
For n = 1 To 15
Value2 = Value2 + ShiftLeft32(ShiftRight32(Value, n) And 1, 15 - n)
Next n
ReverseBits16 = Value2
End Function
Private Function SwapBytes2(ByVal Value As Integer) As Integer
Dim Value2 As Integer
CopyMemory ByVal VarPtr(Value2) + 0, ByVal VarPtr(Value) + 1, 1
CopyMemory ByVal VarPtr(Value2) + 1, ByVal VarPtr(Value) + 0, 1
SwapBytes2 = Value2
End Function