Skip to content

Tools - CRC 计算类

类文件: src\Tools\Crc\cToolsCrc.cls


概述

cToolsCrc 是一个 CRC16/32 计算类,支持逐位计算法和查表法。采用链式调用设计,可方便地连续调用多个方法。

特性:

  • 支持 CRC16-Modbus 计算(多项式 0xA001)
  • 支持 CRC32 计算(多项式 0xEDB88320,IEEE 802.3)
  • 链式调用支持(每个计算函数返回自身实例)
  • 多种数据输入方式(字节数组、HEX字符串、文本字符串)
  • 多种结果输出格式(Long、Currency、字节数组、Hex 字符串)

枚举类型

CRCType 枚举

vb
Public Enum CRCType
    CRC16 = 0
    CRC32 = 1
End Enum

CRCDataType 枚举

vb
Public Enum CRCDataType
    DataType_ByteArray = 0   ' 字节数组
    DataType_HexString = 1   ' HEX字符串(自动处理空格)
    DataType_Text = 2        ' 文本字符串
End Enum

方法

Data (默认成员)

设置数据到内部缓存,供后续计算使用。此方法是类的默认成员,可以省略调用。

vb
Public Function Data(Optional ByVal DataType As CRCDataType = DataType_ByteArray, Optional ByVal Content As Variant = Empty) As cToolsCrc

参数:

参数名类型说明
DataTypeCRCDataType数据类型(可选,默认为字节数组)
ContentVariant数据内容

DataType 说明:

类型说明
DataType_ByteArray0字节数组 (Byte())
DataType_HexString1HEX 字符串,自动处理空格、横杠、冒号等分隔符
DataType_Text2文本字符串,自动转换为 ANSI 字节数组

返回值:

返回 cToolsCrc 实例,支持链式调用。

示例:

vb
Dim CRC As New cToolsCrc
Dim CRCValue As Long

' ========== 方式1: 字节数组 (可省略 DataType 参数) ==========
Dim Bytes() As Byte
Bytes = StrConv("Hello World", vbFromUnicode)
CRCValue = CRC.Data(DataType_ByteArray, Bytes).CalculateCRC16.ReturnLong()
' 或省略 Data 方法名(默认成员)
CRCValue = CRC(DataType_ByteArray, Bytes).CalculateCRC16.ReturnLong()

' ========== 方式2: HEX 字符串 ==========
Dim HexStr As String
HexStr = "48 65 6C 6C 6F"  ' "Hello" 的 HEX
CRCValue = CRC(DataType_HexString, HexStr).CalculateCRC16.ReturnLong()

' 支持多种分隔符格式
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()

' ========== 方式3: 文本字符串 ==========
Dim Text As String
Text = "Hello World"
CRCValue = CRC(DataType_Text, Text).CalculateCRC16.ReturnLong()

CalculateCRC16

计算 CRC16(逐位计算法),基于多项式 0xA001(CRC16-Modbus)。

注意:必须先调用 Data 方法设置数据。

vb
Public Function CalculateCRC16(Optional ByVal StartIndex As Long = 0, Optional ByVal Length As Long = -1) As cToolsCrc

参数:

参数名类型说明
StartIndexLong起始索引(可选,默认为 0)
LengthLong数据长度(可选,默认为 -1 表示计算到数组末尾)

返回值:

返回 cToolsCrc 实例,支持链式调用。

示例:

vb
Dim CRC As New cToolsCrc
Dim CRCValue As Long

' ========== 字节数组方式 ==========
Dim Bytes() As Byte
Bytes = StrConv("Hello World", vbFromUnicode)
CRCValue = CRC(DataType_ByteArray, Bytes).CalculateCRC16.ReturnLong()
Debug.Print "CRC16: " & Hex$(CRCValue)  ' 输出: CRC16: 3AFA

' ========== HEX 字符串方式 ==========
CRCValue = CRC(DataType_HexString, "48 65 6C 6C 6F 20 57 6F 72 6C 64").CalculateCRC16.ReturnLong()

' ========== 文本字符串方式 ==========
CRCValue = CRC(DataType_Text, "Hello World").CalculateCRC16.ReturnLong()

计算部分数据:

vb
' 只计算前 5 个字节(Hello)
Dim CRCValue As Long
CRCValue = CRC(DataType_Text, "Hello World").CalculateCRC16(0, 5).ReturnLong()

ReturnLong

返回 CRC 值作为 Long 类型。

vb
Public Function ReturnLong(Optional ByVal CRCTypeValue As CRCType = CRC16) As Long

参数:

参数名类型说明
CRCTypeValueCRCTypeCRC 类型(可选,默认为 CRC16)

说明:

  • CRC16 返回无符号 16 位值(0-65535)
  • CRC32 返回 Long 类型(若大于 2147483647 则为负数)
  • 需要无符号 32 位结果时建议使用 ReturnCurrencyReturnHex

示例:

vb
' CRC16
Dim CRC16Value As Long
CRC16Value = CRC.CalculateCRC16(Data).ReturnLong(CRC16)

' CRC32
Dim CRC32Value As Long
CRC32Value = CRC.CalculateCRC32(Data).ReturnLong(CRC32)

ReturnCurrency

返回 CRC32 值作为 Currency 类型(无符号 32 位)。

vb
Public Function ReturnCurrency(Optional ByVal CRCTypeValue As CRCType = CRC16) As Currency

参数:

参数名类型说明
CRCTypeValueCRCTypeCRC 类型(可选,默认为 CRC16)

说明:

  • CRC32 返回 0 到 4294967295 的正数
  • CRC16 返回 0 到 65535

示例:

vb
Dim CRC32Value As Currency
CRC32Value = CRC.CalculateCRC32(Data).ReturnCurrency(CRC32)
Debug.Print "CRC32: " & CRC32Value  ' 输出: CRC32: 1243062890

ReturnBytes

返回 CRC 值作为字节数组(高字节在前)。

vb
Public Function ReturnBytes(Optional ByVal CRCTypeValue As CRCType = CRC16) As Byte()

参数:

参数名类型说明
CRCTypeValueCRCTypeCRC 类型(可选,默认为 CRC16)

返回值:

  • CRC16 返回 2 字节数组(高字节在前)
  • CRC32 返回 4 字节数组(高字节在前)

示例:

vb
Dim Result() As Byte
Result = CRC.CalculateCRC16(Data).ReturnBytes()

' Result(0) = 高字节
' Result(1) = 低字节
Debug.Print "Bytes: " & Hex$(Result(0)) & " " & Hex$(Result(1))

ReturnHex

返回 CRC 值作为十六进制字符串(大写)。

vb
Public Function ReturnHex(Optional ByVal CRCTypeValue As CRCType = CRC16) As String

参数:

参数名类型说明
CRCTypeValueCRCTypeCRC 类型(可选,默认为 CRC16)

返回值:

  • CRC16 返回 4 位大写字符串(如 "B001")
  • CRC32 返回 8 位大写字符串(如 "A1B2C3D4")

示例:

vb
Dim HexValue As String
HexValue = CRC.CalculateCRC16(Data).ReturnHex()
Debug.Print "CRC16: " & HexValue  ' 输出: CRC16: 3AFA

' CRC32
Dim CRC32Hex As String
CRC32Hex = CRC.CalculateCRC32(Data).ReturnHex(CRC32)
Debug.Print "CRC32: " & CRC32Hex  ' 输出: CRC32: 4A17B156

ReturnHexString

返回带分隔符的十六进制字符串(适合显示)。

vb
Public Function ReturnHexString(Optional ByVal CRCTypeValue As CRCType = CRC16, Optional ByVal Separator As String = " ") As String

参数:

参数名类型说明
CRCTypeValueCRCTypeCRC 类型(可选,默认为 CRC16)
SeparatorString分隔符(可选,默认为空格)

返回值:

  • CRC16 如 "B0 01"
  • CRC32 如 "A1 B2 C3 D4"

示例:

vb
Dim HexStr As String

' 默认空格分隔
HexStr = CRC.CalculateCRC16(Data).ReturnHexString()
Debug.Print HexStr  ' 输出: 3A FA

' 自定义分隔符
HexStr = CRC.CalculateCRC16(Data).ReturnHexString(CRC16, "-")
Debug.Print HexStr  ' 输出: 3A-FA

' CRC32
HexStr = CRC.CalculateCRC32(Data).ReturnHexString(CRC32, ":")
Debug.Print HexStr  ' 输出: 4A:17:B1:56

完整示例

vb
Private Sub CRCDemo()
    Dim CRC As New cToolsCrc
    Dim Data() As Byte
    Dim CRCValue As Long
    Dim HexResult As String
    
    ' ========== 方式1: 字节数组方式 ==========
    
    Data = StrConv("Hello World", vbFromUnicode)
    
    ' 返回 Long
    CRCValue = CRC(DataType_ByteArray, Data).CalculateCRC16.ReturnLong()
    Debug.Print "CRC16 (Long): " & CRCValue
    
    ' 返回 Hex 字符串
    HexResult = CRC(DataType_ByteArray, Data).CalculateCRC16.ReturnHex()
    Debug.Print "CRC16 (Hex): " & HexResult
    
    ' 返回带分隔符的 Hex
    HexResult = CRC(DataType_ByteArray, Data).CalculateCRC16.ReturnHexString(CRC16, "-")
    Debug.Print "CRC16 (Formatted): " & HexResult
    
    ' ========== 方式2: HEX 字符串方式 ==========
    
    ' 使用 HEX 字符串(自动处理空格)
    HexResult = CRC(DataType_HexString, "48 65 6C 6C 6F 20 57 6F 72 6C 64").CalculateCRC16.ReturnHex()
    Debug.Print "CRC16 from HEX: " & HexResult
    
    ' 使用无空格 HEX
    HexResult = CRC(DataType_HexString, "48656C6C6F20576F726C64").CalculateCRC16.ReturnHex()
    Debug.Print "CRC16 from HEX (no space): " & HexResult
    
    ' 使用横杠分隔
    HexResult = CRC(DataType_HexString, "48-65-6C-6C-6F-20-57-6F-72-6C-64").CalculateCRC16.ReturnHex()
    Debug.Print "CRC16 from HEX (dash): " & HexResult
    
    ' ========== 方式3: 文本字符串方式 ==========
    
    ' 直接使用文本(自动转换为字节数组)
    HexResult = CRC(DataType_Text, "Hello World").CalculateCRC16.ReturnHex()
    Debug.Print "CRC16 from Text: " & HexResult
    
    ' ========== 方式4: 链式调用(默认成员语法) ==========
    
    ' 最简洁的用法:CRC(DataType, Content).Calculate.Return
    Debug.Print CRC(DataType_Text, "Test").CalculateCRC16.ReturnHex()
    
    ' ========== 计算部分数据示例 ==========
    
    ' 只计算前 5 个字节
    Dim PartialCRC As Long
    PartialCRC = CRC(DataType_Text, "Hello World").CalculateCRC16(0, 5).ReturnLong()
    Debug.Print "CRC16 of 'Hello': " & Hex$(PartialCRC)
    
    ' 从第 6 个字节开始计算
    PartialCRC = CRC(DataType_Text, "Hello World").CalculateCRC16(6).ReturnLong()
    Debug.Print "CRC16 of 'World': " & Hex$(PartialCRC)
    
    ' ========== 实用示例:计算 Modbus RTU 帧的 CRC ==========
    
    ' Modbus RTU 请求帧: 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  ' 输出: Modbus CRC: C5 CD
    
    ' 完整的 Modbus 帧
    Debug.Print "Complete Frame: " & ModbusFrame & " " & ModbusCRC
End Sub

技术说明

CRC16 参数

参数
多项式0xA001(CRC16-Modbus)
初始值0xFFFF
输入反转
输出反转
结果异或0x0000

CRC32 参数

参数
多项式0xEDB88320(IEEE 802.3)
初始值0xFFFFFFFF
输入反转
输出反转
结果异或0xFFFFFFFF

注意事项

  1. 数据类型: CRC32 计算使用 Currency 类型来避免 VB6 中 Long 类型的符号位问题(支持无符号 32 位)
  2. 字节序: 所有返回字节数组的方法使用大端序(高字节在前)
  3. 线程安全: 每个 CRC 计算实例是独立的,可以在多线程环境中使用(需确保 VB6 的线程安全)
  4. 性能: 查表法(Table-Driven)比逐位计算快约 8 倍,适合大数据量处理
  5. 默认成员: Data 方法是类的默认成员,可以省略方法名直接调用,如 CRC(DataType_Text, "Hello") 等价于 CRC.Data(DataType_Text, "Hello")
  6. HEX 字符串: DataType_HexString 类型会自动移除空格、横杠、冒号等常见分隔符,支持多种格式

VB6及其LOGO版权为微软公司所有