Skip to content

VBMAN.ToolsCrc - CRC 校验计算对象

概述

VBMAN.ToolsCrc 提供了 CRC16 和 CRC32 校验码计算功能,支持多种数据输入格式(字节数组、HEX字符串、文本),广泛应用于数据校验、通信协议、文件校验等场景。

核心特性

  • 多种算法: 支持 CRC16 (Modbus) 和 CRC32 (IEEE 802.3)
  • 多格式输入: 支持字节数组、HEX字符串、文本字符串
  • 高性能: 内置查找表,计算速度快
  • 链式调用: 流畅的 API 设计
  • 灵活输出: 支持 Long、Currency、字节数组、HEX字符串等多种输出格式

枚举

CRCType

CRC 类型枚举

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) As cToolsCrc

参数:

  • DataType - 数据类型(见 CRCDataType 枚举)
  • Content - 数据内容

示例:

vb
' 字节数组
Dim bytes(0 To 3) As Byte
bytes(0) = &H01: bytes(1) = &H02
bytes(2) = &H03: bytes(3) = &H04

VBMAN.ToolsCrc.Data DataType_ByteArray, bytes

' HEX字符串(自动处理空格、横线、冒号)
VBMAN.ToolsCrc.Data DataType_HexString, "01 02 03 04"
VBMAN.ToolsCrc.Data DataType_HexString, "01-02-03-04"
VBMAN.ToolsCrc.Data DataType_HexString, "01020304"

' 文本字符串
VBMAN.ToolsCrc.Data DataType_Text, "Hello World"

CalculateCRC16

计算 CRC16 校验码(Modbus 多项式 0xA001)

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

参数:

  • StartIndex - 起始索引(默认0)
  • Length - 数据长度(默认-1表示到末尾)

示例:

vb
' 基本计算
Dim crc As Long
crc = VBMAN.ToolsCrc.Data(DataType_HexString, "01 03 00 00 00 0A").CalculateCRC16.ReturnLong
Debug.Print "CRC16: " & Hex(crc)  ' 输出: CRC16: C5CD

' 链式调用
Dim hexResult As String
hexResult = VBMAN.ToolsCrc.Data(DataType_Text, "Hello").CalculateCRC16.ReturnHex
Debug.Print "CRC16 HEX: " & hexResult

结果返回方法

ReturnLong

返回 CRC 值作为 Long 类型

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

说明: CRC32 值大于 2147483647 时会变为负数

示例:

vb
Dim crc As Long
crc = VBMAN.ToolsCrc.Data(DataType_Text, "test").CalculateCRC16.ReturnLong
Debug.Print crc  ' 十进制值

ReturnCurrency

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

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

说明: Currency 类型可表示 0 到 4294967295 的无符号 32 位值

示例:

vb
Dim crc As Currency
crc = VBMAN.ToolsCrc.Data(DataType_Text, "test").CalculateCRC16.ReturnCurrency
Debug.Print crc  ' 正数值,无符号

ReturnBytes

返回 CRC 值作为字节数组

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

说明: CRC16 返回 2字节(高字节在前),CRC32 返回 4字节(高字节在前)

示例:

vb
Dim crcBytes() As Byte
crcBytes = VBMAN.ToolsCrc.Data(DataType_HexString, "01 02").CalculateCRC16.ReturnBytes

' 验证
Debug.Print Hex(crcBytes(0)) & " " & Hex(crcBytes(1))

ReturnHex

返回 CRC 值作为十六进制字符串

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

说明: CRC16 返回 4位大写,CRC32 返回 8位大写

示例:

vb
Dim hexResult As String
hexResult = VBMAN.ToolsCrc.Data(DataType_Text, "Hello World").CalculateCRC16.ReturnHex
Debug.Print hexResult  ' 例如: B001

ReturnHexString

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

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

示例:

vb
Dim hexWithSpace As String
hexWithSpace = VBMAN.ToolsCrc.Data(DataType_HexString, "01 02 03").CalculateCRC16.ReturnHexString(CRC16, " ")
Debug.Print hexWithSpace  ' 例如: B0 01

Dim hexWithDash As String
hexWithDash = VBMAN.ToolsCrc.Data(DataType_HexString, "01 02 03").CalculateCRC16.ReturnHexString(CRC16, "-")
Debug.Print hexWithDash   ' 例如: B0-01

综合示例

示例1: Modbus RTU CRC16 计算

vb
Private Sub ModbusCrcExample()
    ' Modbus RTU 帧: 设备地址 01, 功能码 03, 起始地址 0000, 寄存器数 000A
    Dim frame As String
    frame = "01 03 00 00 00 0A"
    
    ' 计算 CRC16
    Dim crcResult As String
    crcResult = VBMAN.ToolsCrc.Data(DataType_HexString, frame).CalculateCRC16.ReturnHexString(CRC16, " ")
    
    Debug.Print "数据帧: " & frame
    Debug.Print "CRC16: " & crcResult  ' 输出: C5 CD
    
    ' 完整帧
    Debug.Print "完整帧: " & frame & " " & crcResult
End Sub

示例2: 数据帧校验

vb
Private Function VerifyFrame(dataFrame As String, expectedCrc As String) As Boolean
    ' 提取数据和 CRC
    Dim dataPart As String
    Dim crcPart As String
    
    dataPart = Left(dataFrame, Len(dataFrame) - 4)
    crcPart = Right(dataFrame, 4)
    
    ' 计算 CRC
    Dim calculatedCrc As String
    calculatedCrc = VBMAN.ToolsCrc.Data(DataType_HexString, dataPart).CalculateCRC16.ReturnHex
    
    ' 比较
    VerifyFrame = (UCase(calculatedCrc) = UCase(expectedCrc))
End Function

Private Sub TestVerify()
    Dim frame As String
    frame = "01 03 00 00 00 0A C5 CD"
    
    If VerifyFrame(frame, "C5CD") Then
        Debug.Print "CRC 校验通过"
    Else
        Debug.Print "CRC 校验失败"
    End If
End Sub

示例3: 串口通信数据打包

vb
Private Function PackSerialCommand(cmdCode As Byte, param As Byte) As Byte()
    ' 构建数据帧
    Dim data(0 To 1) As Byte
    data(0) = cmdCode
    data(1) = param
    
    ' 计算 CRC16
    Dim crcBytes() As Byte
    crcBytes = VBMAN.ToolsCrc.Data(DataType_ByteArray, data).CalculateCRC16.ReturnBytes(CRC16)
    
    ' 组装完整帧: 数据 + CRC
    Dim frame() As Byte
    ReDim frame(0 To 3)
    frame(0) = data(0)
    frame(1) = data(1)
    frame(2) = crcBytes(0)  ' CRC 高字节
    frame(3) = crcBytes(1)  ' CRC 低字节
    
    PackSerialCommand = frame
End Function

Private Sub SendCommand()
    Dim cmd() As Byte
    cmd = PackSerialCommand(&H10, &H01)  ' 命令 0x10, 参数 0x01
    
    ' 发送到串口
    ' MSComm1.Output = cmd
End Sub

示例4: 批量 CRC 计算

vb
Private Sub BatchCrcCalculation()
    Dim testData As Variant
    testData = Array( _
        "01 03 00 00 00 0A", _
        "01 03 00 64 00 02", _
        "01 06 00 01 00 64" _
    )
    
    Dim i As Integer
    For i = LBound(testData) To UBound(testData)
        Dim dataStr As String
        dataStr = testData(i)
        
        Dim crcHex As String
        crcHex = VBMAN.ToolsCrc.Data(DataType_HexString, dataStr).CalculateCRC16.ReturnHex
        
        Debug.Print "数据: " & dataStr & " -> CRC16: " & crcHex
    Next i
End Sub

示例5: 文件 CRC 校验

vb
Private Function CalculateFileCrc(filePath As String) As String
    On Error GoTo ErrorHandler
    
    ' 读取文件到字节数组
    Dim fileNum As Integer
    fileNum = FreeFile
    
    Open filePath For Binary As #fileNum
    
    Dim fileSize As Long
    fileSize = LOF(fileNum)
    
    Dim fileBytes() As Byte
    ReDim fileBytes(0 To fileSize - 1)
    
    Get #fileNum, , fileBytes
    Close #fileNum
    
    ' 计算 CRC16
    Dim crcHex As String
    crcHex = VBMAN.ToolsCrc.Data(DataType_ByteArray, fileBytes).CalculateCRC16.ReturnHex
    
    CalculateFileCrc = crcHex
    Exit Function
    
ErrorHandler:
    CalculateFileCrc = ""
End Function

Private Sub CheckFileIntegrity()
    Dim crc As String
    crc = CalculateFileCrc("C:\\data\\important.bin")
    Debug.Print "文件 CRC16: " & crc
End Sub

最佳实践

  1. HEX 格式灵活: HEX 字符串支持空格、横线、冒号分隔,自动清理
  2. 字节序注意: ReturnBytes 返回高字节在前(大端序)
  3. 无符号处理: CRC32 建议使用 ReturnCurrency 避免符号问题
  4. 预初始化: 类初始化时自动构建查找表,无需手动调用
  5. 错误检查: 计算前确保数据已正确设置

算法说明

CRC16 (Modbus)

  • 多项式: 0xA001 (或 0x8005 反转)
  • 初始值: 0xFFFF
  • 结果处理: 无额外处理

CRC32 (IEEE 802.3)

  • 多项式: 0xEDB88320
  • 初始值: 0xFFFFFFFF
  • 结果处理: 与 0xFFFFFFFF 异或(取反)

常见 CRC 值参考

vb
' 空数据 CRC16
Debug.Print VBMAN.ToolsCrc.Data(DataType_ByteArray, Array()).CalculateCRC16.ReturnHex
' 结果: FFFF

' "123456789" 文本 CRC16
Debug.Print VBMAN.ToolsCrc.Data(DataType_Text, "123456789").CalculateCRC16.ReturnHex
' 标准结果: 31C3

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