>i found this vfp code that gives the same results as sys(2007)
>
http://fox.wikis.com/wc.dll?Wiki~CRC16>
>and this
>lnCRC16 = SYS(2007,"String to be CheckSummed")
>is the same result as this
>lnCRC16 = STR(bobcrc(-1,"String to be CheckSummed","16"))
>
>now I just have to figure out how to translate the below VFP code to c#
>
>PARAMETERS lnStartVal, lcBlockTxt, lcBitLen
>DO CASE
> CASE PCOUNT() < 2
> WAIT WINDOW "Not enough paramters passed to ";
> +"CRC(lnStartVal, lcBlockTxt, lcBitLen) function."
> RET4URN
> 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
Try this:
private static int CRC(string blockText, string bitLength = "16", int startVal = -1)
{
var actualBitLength = bitLength == "32" ? 32773 : 4129;
var powers = Enumerable.Range(0, 8).Select(power => (int)Math.Pow(2, power)).ToArray();
var crc = startVal;
for (int outerLoop = 0; outerLoop < blockText.Length; outerLoop++)
{
var byteVal = (int)blockText[outerLoop];
for (int innerLoop = 8; innerLoop >= 1; innerLoop--)
{
var testBit = (((crc & 32768) == 32768) != ((byteVal & powers[innerLoop - 1]) == powers[innerLoop - 1]));
crc = (crc & 32767) * 2;
if (testBit)
crc = crc ^ actualBitLength;
}
}
return crc;
}