Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1449

modCRC.bas

$
0
0
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.

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


Viewing all articles
Browse latest Browse all 1449

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>