I was working last week on a Microsoft Access application and I needed to get some data from a webserver running Apache/PHP. Exchanging data with the server was easy, the WinHTTP and XML ActiveX library components are really cool and easy to use for that. But then I came unto some unexpected trouble when I tried to use a CRC check on both the VBA and PHP side to quickly add some integrity checking on the exchanged data.
I already had a VBA routine computing a CRC checksum, but had none on the PHP side. So I thought “google it up”, pick the first CRC checksum routine that comes up and use it, easy. By the way, if you want to refresh your neurons about the CRC stuff, you can read more about that in wikipedia.
To make a long story short, there are many algorithms out there, for VBA and PHP, and to find two that go well along and yield the same result, it takes some time and tries.
So, here are the two ones I now use. Enjoy !
VBA Cyclic redundancy check CRC16_2 function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
'Compute a CRC for a string (16bits CRC, CCITT inverted) 'Original source: 'http://www.xtremevbtalk.com/showthread.php?t=318655 'Added string param instead od byte array, ErrHandler and second optional parameter InputCrc Private Function CRC16_2(ByVal psData As String, Optional ByVal plInitCrc As Variant) As Long Const CRC_POLYNOM As Long = &H8408& Const CRC_PRESET As Long = &HFFFF& Dim crc As Long, i As Long, j As Long Dim Buffer() As Byte On Error GoTo ErrHandler Buffer = StrConv(psData, vbFromUnicode) If IsMissing(plInitCrc) Then crc = CRC_PRESET 'unsigned internal CRC = CRC_PRESET Else crc = plInitCrc End If For i = 0 To UBound(Buffer) 'for(i=0; i < cnt; i++) crc = crc Xor Buffer(i) 'crc ^= Buffer[i] For j = 0 To 7 'for(j=0; j<8;j++) If (crc And 1) Then 'if(crc & 0x0001) crc = (crc \ 2) Xor CRC_POLYNOM 'crc=(crc>>1)^CRC_POLYNOM; Else crc = (crc \ 2) 'crc=(crc>>1) End If Next j Next i CRC16_2 = crc ErrHandler: End Function |
And in PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// CCITT, X24 define('CRC16POLYI',0x8408); /* * Source: https://forums.digitalpoint.com/threads/php-define-function-calculate-crc-16-ccitt.2584389/ * Note: no second parameter here as on the VBA version */ function CRC16Inverse($buffer) { $result = 0xFFFF; if ( ($length = strlen($buffer)) > 0) { for ($offset = 0; $offset < $length; $offset++) { $result ^= ord($buffer[$offset]); for ($bitwise = 0; $bitwise < 8; $bitwise++) { $lowBit = $result & 0x0001; $result >>= 1; if ($lowBit) { $result ^= CRC16POLYI; } } } } return $result; } |
Recent Comments