lcStr = "Most anything you want to put in here!" ?transform(bobcrc(-1, lcStr, "16"), "@0x ") ?transform(val(sys(2007, lcStr)), "@0x ")And now for the "generic" CRC routine (still with the credits!):
* Program....: BOBCRC.PRG * Version....: 1.0 * Author.....: Bob Herguth, Based upon PowerBASIC Code by Coridon Henshaw * Date.......: June 9, 1997 * Compiler...: FoxPro 2.6a * Abstract...: 16 and 32 bit CRC calaculator routine for data blocks. * lcBlockTxt: The text block to calculate a CRC for. * lcBitLen: A text value ("16" or "32")indicating whether * to return a 16 or 32 bit CRC. * Changes....: PARAMETERS lnStartVal, lcBlockTxt, lcBitLen DO CASE CASE PCOUNT() < 2 WAIT WINDOW "Not enough paramters passed to CRC(lnStartVal, lcBlockTxt, lcBitLen) function." RETURN CASE PCOUNT() < 3 lcBitLen = "16" ENDCASE DIMENSION laPower[8] && For the 8 laPowers of 2 PRIVATE lnCRC, lnPower, TestBit lnBitLen = IIF(lcBitLen="32",32773,4129) && 1021 hex (16bit), 8005 hex (32bit) * Precalculated values will improve performance in FOR J Code FOR lnPower = 1 TO 8 laPower[lnPower] = 2^(lnPower-1) NEXT lnPower lnCRC = lnStartVal && Reset for Each Text Block FOR OutLoop = 1 TO LEN(lcBlockTxt) && Calculate for Length of Block ByteVal = ASC(SUBSTR(lcBlockTxt, OutLoop, 1)) FOR InLoop = 8 TO 1 STEP - 1 TestBit = ((BITAND(lnCRC,32768) = 32768) AND NOT (BITAND(ByteVal, laPower(InLoop)) = laPower(InLoop))) OR; (!(BITAND(lnCRC,32768) = 32768) AND (BITAND(ByteVal, laPower(InLoop)) = laPower(InLoop))) lnCRC = BITAND(lnCRC,32767)*2 IF TestBit lnCRC = BITXOR(lnCRC,lnBitLen) ENDIF NEXT InLoop NEXT OutLoop RETURN lnCRC && Return the Word Value FUNCTION Xd0bit PARAMETER Bitno, A PRIVATE Remainder, I, Highord Highord = INT(IIF(A>1,LOG(A)*1.442695041,0)) IF Bitno>Highord RETURN .F. ENDIF FOR I = 0 TO Highord IF I=Bitno RETURN IIF(IIF(A=1,1,MOD(A,2))=1,.T.,.F.) ENDIF IF A=0 RETURN .F. ENDIF A = INT(A/2) NEXTRick