Tools - CRC Calculation Class
Class File:
src\Tools\Crc\cToolsCrc.cls
Overview
cToolsCrc is a CRC16/32 calculation class that supports bit-by-bit calculation and table lookup methods. It uses a fluent/chaining design for easy consecutive method calls.
Features:
- Supports CRC16-Modbus calculation (polynomial 0xA001)
- Supports CRC32 calculation (polynomial 0xEDB88320, IEEE 802.3)
- Method chaining support (each calculation function returns its own instance)
- Multiple data input methods (byte array, HEX string, text string)
- Multiple result output formats (Long, Currency, byte array, Hex string)
Enumerations
CRCType Enum
Public Enum CRCType
CRC16 = 0
CRC32 = 1
End EnumCRCDataType Enum
Public Enum CRCDataType
DataType_ByteArray = 0 ' Byte array
DataType_HexString = 1 ' HEX string (automatically handles spaces)
DataType_Text = 2 ' Text string
End EnumMethods
Data (Default Member)
Sets data to the internal buffer for subsequent calculations. This method is the default member of the class and can be omitted.
Public Function Data(Optional ByVal DataType As CRCDataType = DataType_ByteArray, Optional ByVal Content As Variant = Empty) As cToolsCrcParameters:
| Parameter | Type | Description |
|---|---|---|
DataType | CRCDataType | Data type (optional, defaults to byte array) |
Content | Variant | Data content |
DataType Description:
| Type | Value | Description |
|---|---|---|
DataType_ByteArray | 0 | Byte array (Byte()) |
DataType_HexString | 1 | HEX string, automatically handles spaces, dashes, colons, etc. |
DataType_Text | 2 | Text string, automatically converted to ANSI byte array |
Return Value:
Returns cToolsCrc instance, supporting method chaining.
Example:
Dim CRC As New cToolsCrc
Dim CRCValue As Long
' ========== Method 1: Byte array (can omit DataType parameter) ==========
Dim Bytes() As Byte
Bytes = StrConv("Hello World", vbFromUnicode)
CRCValue = CRC.Data(DataType_ByteArray, Bytes).CalculateCRC16.ReturnLong()
' Or omit Data method name (default member)
CRCValue = CRC(DataType_ByteArray, Bytes).CalculateCRC16.ReturnLong()
' ========== Method 2: HEX string ==========
Dim HexStr As String
HexStr = "48 65 6C 6C 6F" ' HEX of "Hello"
CRCValue = CRC(DataType_HexString, HexStr).CalculateCRC16.ReturnLong()
' Supports multiple delimiter formats
CRC(DataType_HexString, "48-65-6C-6C-6F").CalculateCRC16.ReturnLong()
CRC(DataType_HexString, "48:65:6C:6C:6F").CalculateCRC16.ReturnLong()
CRC(DataType_HexString, "48656C6C6F").CalculateCRC16.ReturnLong()
' ========== Method 3: Text string ==========
Dim Text As String
Text = "Hello World"
CRCValue = CRC(DataType_Text, Text).CalculateCRC16.ReturnLong()CalculateCRC16
Calculates CRC16 (bit-by-bit calculation method) based on polynomial 0xA001 (CRC16-Modbus).
Note: You must call the Data method to set data first.
Public Function CalculateCRC16(Optional ByVal StartIndex As Long = 0, Optional ByVal Length As Long = -1) As cToolsCrcParameters:
| Parameter | Type | Description |
|---|---|---|
StartIndex | Long | Starting index (optional, defaults to 0) |
Length | Long | Data length (optional, defaults to -1 meaning calculate to end of array) |
Return Value:
Returns cToolsCrc instance, supporting method chaining.
Example:
Dim CRC As New cToolsCrc
Dim CRCValue As Long
' ========== Byte array method ==========
Dim Bytes() As Byte
Bytes = StrConv("Hello World", vbFromUnicode)
CRCValue = CRC(DataType_ByteArray, Bytes).CalculateCRC16.ReturnLong()
Debug.Print "CRC16: " & Hex$(CRCValue) ' Output: CRC16: 3AFA
' ========== HEX string method ==========
CRCValue = CRC(DataType_HexString, "48 65 6C 6C 6F 20 57 6F 72 6C 64").CalculateCRC16.ReturnLong()
' ========== Text string method ==========
CRCValue = CRC(DataType_Text, "Hello World").CalculateCRC16.ReturnLong()Calculate Partial Data:
' Only calculate first 5 bytes (Hello)
Dim CRCValue As Long
CRCValue = CRC(DataType_Text, "Hello World").CalculateCRC16(0, 5).ReturnLong()ReturnLong
Returns the CRC value as Long type.
Public Function ReturnLong(Optional ByVal CRCTypeValue As CRCType = CRC16) As LongParameters:
| Parameter | Type | Description |
|---|---|---|
CRCTypeValue | CRCType | CRC type (optional, defaults to CRC16) |
Description:
- CRC16 returns unsigned 16-bit value (0-65535)
- CRC32 returns Long type (negative if greater than 2147483647)
- For unsigned 32-bit results, use
ReturnCurrencyorReturnHex
Example:
' CRC16
Dim CRC16Value As Long
CRC16Value = CRC.CalculateCRC16(Data).ReturnLong(CRC16)
' CRC32
Dim CRC32Value As Long
CRC32Value = CRC.CalculateCRC32(Data).ReturnLong(CRC32)ReturnCurrency
Returns the CRC32 value as Currency type (unsigned 32-bit).
Public Function ReturnCurrency(Optional ByVal CRCTypeValue As CRCType = CRC16) As CurrencyParameters:
| Parameter | Type | Description |
|---|---|---|
CRCTypeValue | CRCType | CRC type (optional, defaults to CRC16) |
Description:
- CRC32 returns positive number from 0 to 4294967295
- CRC16 returns 0 to 65535
Example:
Dim CRC32Value As Currency
CRC32Value = CRC.CalculateCRC32(Data).ReturnCurrency(CRC32)
Debug.Print "CRC32: " & CRC32Value ' Output: CRC32: 1243062890ReturnBytes
Returns the CRC value as a byte array (high byte first).
Public Function ReturnBytes(Optional ByVal CRCTypeValue As CRCType = CRC16) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
CRCTypeValue | CRCType | CRC type (optional, defaults to CRC16) |
Return Value:
- CRC16 returns 2-byte array (high byte first)
- CRC32 returns 4-byte array (high byte first)
Example:
Dim Result() As Byte
Result = CRC.CalculateCRC16(Data).ReturnBytes()
' Result(0) = High byte
' Result(1) = Low byte
Debug.Print "Bytes: " & Hex$(Result(0)) & " " & Hex$(Result(1))ReturnHex
Returns the CRC value as a hexadecimal string (uppercase).
Public Function ReturnHex(Optional ByVal CRCTypeValue As CRCType = CRC16) As StringParameters:
| Parameter | Type | Description |
|---|---|---|
CRCTypeValue | CRCType | CRC type (optional, defaults to CRC16) |
Return Value:
- CRC16 returns 4-character uppercase string (e.g., "B001")
- CRC32 returns 8-character uppercase string (e.g., "A1B2C3D4")
Example:
Dim HexValue As String
HexValue = CRC.CalculateCRC16(Data).ReturnHex()
Debug.Print "CRC16: " & HexValue ' Output: CRC16: 3AFA
' CRC32
Dim CRC32Hex As String
CRC32Hex = CRC.CalculateCRC32(Data).ReturnHex(CRC32)
Debug.Print "CRC32: " & CRC32Hex ' Output: CRC32: 4A17B156ReturnHexString
Returns a hexadecimal string with separators (suitable for display).
Public Function ReturnHexString(Optional ByVal CRCTypeValue As CRCType = CRC16, Optional ByVal Separator As String = " ") As StringParameters:
| Parameter | Type | Description |
|---|---|---|
CRCTypeValue | CRCType | CRC type (optional, defaults to CRC16) |
Separator | String | Separator character (optional, defaults to space) |
Return Value:
- CRC16 e.g., "B0 01"
- CRC32 e.g., "A1 B2 C3 D4"
Example:
Dim HexStr As String
' Default space separator
HexStr = CRC.CalculateCRC16(Data).ReturnHexString()
Debug.Print HexStr ' Output: 3A FA
' Custom separator
HexStr = CRC.CalculateCRC16(Data).ReturnHexString(CRC16, "-")
Debug.Print HexStr ' Output: 3A-FA
' CRC32
HexStr = CRC.CalculateCRC32(Data).ReturnHexString(CRC32, ":")
Debug.Print HexStr ' Output: 4A:17:B1:56Complete Example
Private Sub CRCDemo()
Dim CRC As New cToolsCrc
Dim Data() As Byte
Dim CRCValue As Long
Dim HexResult As String
' ========== Method 1: Byte array method ==========
Data = StrConv("Hello World", vbFromUnicode)
' Return Long
CRCValue = CRC(DataType_ByteArray, Data).CalculateCRC16.ReturnLong()
Debug.Print "CRC16 (Long): " & CRCValue
' Return Hex string
HexResult = CRC(DataType_ByteArray, Data).CalculateCRC16.ReturnHex()
Debug.Print "CRC16 (Hex): " & HexResult
' Return Hex with separators
HexResult = CRC(DataType_ByteArray, Data).CalculateCRC16.ReturnHexString(CRC16, "-")
Debug.Print "CRC16 (Formatted): " & HexResult
' ========== Method 2: HEX string method ==========
' Use HEX string (automatically handles spaces)
HexResult = CRC(DataType_HexString, "48 65 6C 6C 6F 20 57 6F 72 6C 64").CalculateCRC16.ReturnHex()
Debug.Print "CRC16 from HEX: " & HexResult
' Use HEX without spaces
HexResult = CRC(DataType_HexString, "48656C6C6F20576F726C64").CalculateCRC16.ReturnHex()
Debug.Print "CRC16 from HEX (no space): " & HexResult
' Use dash separator
HexResult = CRC(DataType_HexString, "48-65-6C-6C-6F-20-57-6F-72-6C-64").CalculateCRC16.ReturnHex()
Debug.Print "CRC16 from HEX (dash): " & HexResult
' ========== Method 3: Text string method ==========
' Use text directly (automatically converted to byte array)
HexResult = CRC(DataType_Text, "Hello World").CalculateCRC16.ReturnHex()
Debug.Print "CRC16 from Text: " & HexResult
' ========== Method 4: Method chaining (default member syntax) ==========
' Most concise usage: CRC(DataType, Content).Calculate.Return
Debug.Print CRC(DataType_Text, "Test").CalculateCRC16.ReturnHex()
' ========== Partial data calculation example ==========
' Only calculate first 5 bytes
Dim PartialCRC As Long
PartialCRC = CRC(DataType_Text, "Hello World").CalculateCRC16(0, 5).ReturnLong()
Debug.Print "CRC16 of 'Hello': " & Hex$(PartialCRC)
' Calculate from 6th byte
PartialCRC = CRC(DataType_Text, "Hello World").CalculateCRC16(6).ReturnLong()
Debug.Print "CRC16 of 'World': " & Hex$(PartialCRC)
' ========== Practical example: Calculate CRC for Modbus RTU frame ==========
' Modbus RTU request frame: 01 03 00 00 00 0A
Dim ModbusFrame As String
Dim ModbusCRC As String
ModbusFrame = "01 03 00 00 00 0A"
ModbusCRC = CRC(DataType_HexString, ModbusFrame).CalculateCRC16.ReturnHexString(CRC16, " ")
Debug.Print "Modbus CRC: " & ModbusCRC ' Output: Modbus CRC: C5 CD
' Complete Modbus frame
Debug.Print "Complete Frame: " & ModbusFrame & " " & ModbusCRC
End SubTechnical Specifications
CRC16 Parameters
| Parameter | Value |
|---|---|
| Polynomial | 0xA001 (CRC16-Modbus) |
| Initial Value | 0xFFFF |
| Input Reflected | Yes |
| Output Reflected | Yes |
| Final XOR | 0x0000 |
CRC32 Parameters
| Parameter | Value |
|---|---|
| Polynomial | 0xEDB88320 (IEEE 802.3) |
| Initial Value | 0xFFFFFFFF |
| Input Reflected | Yes |
| Output Reflected | Yes |
| Final XOR | 0xFFFFFFFF |
Notes
- Data Type: CRC32 calculation uses
Currencytype to avoid VB6's Long type sign bit issues (supports unsigned 32-bit) - Byte Order: All methods returning byte arrays use big-endian (high byte first)
- Thread Safety: Each CRC calculation instance is independent and can be used in multi-threaded environments (ensure VB6 thread safety)
- Performance: Table-Driven method is about 8x faster than bit-by-bit calculation, suitable for large data processing
- Default Member: The
Datamethod is the default member of the class and can be called without the method name, e.g.,CRC(DataType_Text, "Hello")is equivalent toCRC.Data(DataType_Text, "Hello") - HEX String:
DataType_HexStringtype automatically removes common separators like spaces, dashes, colons, supporting multiple formats