Attribute VB_Name = "basCRC24" Option Explicit ' basCRC24: Calculates CRC-24 checksum for a given message string ' Version 1. Published 4 June 2003. ' Updated 17 June 2020 - changed license on this code to MIT. ' ******************************* LICENSE *********************************** ' * Copyright (C) 2003-20 David Ireland, DI Management Services Pty Limited. ' * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net> ' * The code in this module is licensed under the terms of the MIT license. ' * For a copy, see <http://opensource.org/licenses/MIT> ' *************************************************************************** ' Please forward comments or bug reports to https://di-mgt.com.au/contact ' FUNCTIONS:- ' Public Function CRC24_Bytes(abMessage() As Byte) As Long ' - Returns the 24-bit CRC for an array of Bytes ' Public Function CRC24_String(sMessage As String) As Long ' - Returns the 24-bit CRC for a String ' The function cv_BytesFromHex() used in the test is available in ' the module basConvert.txt Public Function Test_CRC24() ' Tests for CRC-24 algorithm. Correct output is:- 'CRC24(3F214365876616AB15387D5D59)=BA0568 'CRC24(89003F0305...)=5982EA 'CRC24('hello world')=B03CB7 'CRC24('Hello world')=EDAB02 'CRC24('123456789')=21CF02 Dim sTestHex As String Dim sTest As String Dim abOctets() As Byte Dim ulCRC As Long sTestHex = "3F214365876616AB15387D5D59" abOctets = cv_BytesFromHex(sTestHex) ulCRC = CRC24_Bytes(abOctets) Debug.Print "CRC24(" & sTestHex & ")=" & Hex(ulCRC) ' This test data is from a sample PGP message. sTestHex = "89003F0305013E978A669E02D8AE8DFD6EDE11027520009E2B90532BFD46E8FF1305758BE8DEC71C" & _ "2C50FCCB009F6F6D5A91A80B89B7D570A6FE382BDEC5951426A6CD" abOctets = cv_BytesFromHex(sTestHex) ulCRC = CRC24_Bytes(abOctets) Debug.Print "CRC24(" & Left(sTestHex, 10) & "...)=" & Hex(ulCRC) sTest = "hello world" ulCRC = CRC24_String(sTest) Debug.Print "CRC24('" & sTest & "')=" & Hex(ulCRC) sTest = "Hello world" ulCRC = CRC24_String(sTest) Debug.Print "CRC24('" & sTest & "')=" & Hex(ulCRC) sTest = "123456789" ulCRC = CRC24_String(sTest) Debug.Print "CRC24('" & sTest & "')=" & Hex(ulCRC) End Function Public Function CRC24_Bytes(abMessage() As Byte) As Long Const CRC24_INIT As Long = &HB704CE Const CRC24_POLY As Long = &H1864CFB Dim i As Long Dim j As Integer Dim ulCRC As Long ulCRC = CRC24_INIT For i = LBound(abMessage) To UBound(abMessage) ulCRC = ulCRC Xor ulShiftLeftBy16(abMessage(i)) For j = 0 To 7 ulCRC = ulShiftLeftByOne(ulCRC) If (ulCRC And &H1000000) <> 0 Then ulCRC = ulCRC Xor CRC24_POLY End If Next Next CRC24_Bytes = ulCRC And &HFFFFFF End Function Public Function CRC24_String(sMessage As String) As Long Dim abMessage() As Byte ' Use proper VB function to get an array of bytes ' thus avoiding problems with Unicode/ANSI/DBCS character sets abMessage = StrConv(sMessage, vbFromUnicode) CRC24_String = CRC24_Bytes(abMessage) End Function Private Function ulShiftLeftBy16(ByVal wordX As Long) As Long ' Shift 32-bit long value to left by 16 bits ' i.e. VB equivalent of "wordX << 16" in C ' Avoiding problem with sign bit ' Copyright (C) 2000-03 DI Management Services Pty Ltd ulShiftLeftBy16 = (wordX And &H7FFF&) * &H10000 If (wordX And &H8000&) <> 0 Then ulShiftLeftBy16 = ulShiftLeftBy16 Or &H80000000 End If End Function Private Function ulShiftLeftByOne(ByVal wordX As Long) As Long ' Shift 32-bit long value to left by 1 bits ' i.e. VB equivalent of "wordX << 1" in C ' Avoiding problem with sign bit ' Copyright (C) 2000-03 DI Management Services Pty Ltd ulShiftLeftByOne = (wordX And &H7FFFFFFF) * &H2 If (wordX And &H8000000) <> 0 Then ulShiftLeftByOne = ulShiftLeftByOne Or &H80000000 End If End Function