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 EnumCRCDataType 枚举
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参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
DataType | CRCDataType | 数据类型(可选,默认为字节数组) |
Content | Variant | 数据内容 |
DataType 说明:
| 类型 | 值 | 说明 |
|---|---|---|
DataType_ByteArray | 0 | 字节数组 (Byte()) |
DataType_HexString | 1 | HEX 字符串,自动处理空格、横杠、冒号等分隔符 |
DataType_Text | 2 | 文本字符串,自动转换为 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参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
StartIndex | Long | 起始索引(可选,默认为 0) |
Length | Long | 数据长度(可选,默认为 -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参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
CRCTypeValue | CRCType | CRC 类型(可选,默认为 CRC16) |
说明:
- CRC16 返回无符号 16 位值(0-65535)
- CRC32 返回 Long 类型(若大于 2147483647 则为负数)
- 需要无符号 32 位结果时建议使用
ReturnCurrency或ReturnHex
示例:
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参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
CRCTypeValue | CRCType | CRC 类型(可选,默认为 CRC16) |
说明:
- CRC32 返回 0 到 4294967295 的正数
- CRC16 返回 0 到 65535
示例:
vb
Dim CRC32Value As Currency
CRC32Value = CRC.CalculateCRC32(Data).ReturnCurrency(CRC32)
Debug.Print "CRC32: " & CRC32Value ' 输出: CRC32: 1243062890ReturnBytes
返回 CRC 值作为字节数组(高字节在前)。
vb
Public Function ReturnBytes(Optional ByVal CRCTypeValue As CRCType = CRC16) As Byte()参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
CRCTypeValue | CRCType | CRC 类型(可选,默认为 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参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
CRCTypeValue | CRCType | CRC 类型(可选,默认为 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: 4A17B156ReturnHexString
返回带分隔符的十六进制字符串(适合显示)。
vb
Public Function ReturnHexString(Optional ByVal CRCTypeValue As CRCType = CRC16, Optional ByVal Separator As String = " ") As String参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
CRCTypeValue | CRCType | CRC 类型(可选,默认为 CRC16) |
Separator | String | 分隔符(可选,默认为空格) |
返回值:
- 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 |
注意事项
- 数据类型: CRC32 计算使用
Currency类型来避免 VB6 中 Long 类型的符号位问题(支持无符号 32 位) - 字节序: 所有返回字节数组的方法使用大端序(高字节在前)
- 线程安全: 每个 CRC 计算实例是独立的,可以在多线程环境中使用(需确保 VB6 的线程安全)
- 性能: 查表法(Table-Driven)比逐位计算快约 8 倍,适合大数据量处理
- 默认成员:
Data方法是类的默认成员,可以省略方法名直接调用,如CRC(DataType_Text, "Hello")等价于CRC.Data(DataType_Text, "Hello") - HEX 字符串:
DataType_HexString类型会自动移除空格、横杠、冒号等常见分隔符,支持多种格式