1. -- CRC object
  2. -- Cyclic Redundancy Check
  3. ----------------------------------------------
  4. -- Provided by Robert Ramsden (05 November 2002)
  5. -- rob@digitaljunction.co.za
  6. ----------------------------------------------
  7. -- Usage:
  8. -- Instantiate a copy of this object.
  9. -- Use the mSetup method to set all the default object variables.
  10. -- Should you require a different seed other than the CRC-32 standard,
  11. --   seed the algorithm using the mSeedCRC method.
  12. --
  13. -- To add data to the crc algorithim use mAppendToCRC and supply
  14. --   the sting to append to the crc.
  15. -- Once completed request mReturnCRC to return the value
  16. --   of the calculated CRC.
  17. -- The reason for breaking the algorithm into an append
  18. --   and a return, is that the data is significantly changed
  19. --   on output.
  20. -- This method therefore allows data to be read in chuncks
  21. --   without affecting the outcome of the CRC.
  22. ----------------------------------------------
  23. -- Globals
  24.  
  25. ----------------------------------------------
  26. -- Properties
  27.  
  28. property pCRCTable
  29. property pCrc
  30. property pSeedCRC
  31. property pBitShiftList
  32. property pUpperMasksList
  33.  
  34. ----------------------------------------------
  35. on new(me)
  36.   -- return the object with a new memory reference
  37.  
  38.   return me
  39.  
  40. end new
  41. ----------------------------------------------
  42. on mInit(me)
  43.   -- return the object with the same memory reference
  44.  
  45.   return me
  46.  
  47. end mInit
  48. ----------------------------------------------
  49. on mSetup me, lSeed
  50.   -- Setup the CRC object.
  51.   -- Create lookup tables for BitShifting and BitMasks
  52.   -- Seed the CRC algorithm with the supplied seed parameter.
  53.   -- Initiate the CRC lookup table
  54.  
  55.   pBitShiftList = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, -2147483648]
  56.   pUpperMasksList = [2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0]
  57.   pSeedCRC = lSeed
  58.   mSeedCRC me, pSeedCRC
  59.   mInitCRCTable me
  60.  
  61. end mSetup
  62. ----------------------------------------------
  63. on mSeedCRC me, lSeed
  64.   -- Seed the CRC with a seed value of use the
  65.   -- default hex value : 0xffffffff
  66.   --         integer value : -1 or 4294967295
  67.  
  68.   if voidP(pSeedCRC) then
  69.     pCrc = -1 -- 0xffffffff
  70.   end if
  71.  
  72. end mSeedCRC
  73. ----------------------------------------------
  74. on mReturnCRC(me)
  75.   -- Returns the current CRC
  76.   -- Resets the CRC Seed to the initial value for next CRC opperation.
  77.  
  78.   lCrc = bitXOR(pCrc, -1)
  79.   mSeedCRC me, pSeedCRC
  80.   return lCrc
  81.  
  82. end mReturnCRC
  83. ----------------------------------------------
  84. on mAppendToCRC me, lString
  85.   --// This function uses the crc32_table lookup table
  86.   --// to generate a CRC for csData
  87.   --int CCRCfileDlg::Get_CRC(CString &csData, DWORD dwSize)
  88.   --{
  89.   --    // Be sure to use unsigned variables,
  90.   --    // because negative values introduce high bits
  91.   --    // where zero bits are required.
  92.   --    ULONG  crc(0xffffffff);
  93.   --    int len;
  94.   --    unsigned char* buffer;
  95.   --
  96.   --    len = dwSize;
  97.   --    // Save the text in the buffer.
  98.   --    buffer = (unsigned char*)(LPCTSTR)csData;
  99.   --    // Perform the algorithm on each character
  100.   --    // in the string, using the lookup table values.
  101.   --    while(len--)
  102.   --        crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *buffer++];
  103.   --    // Exclusive OR the result with the beginning value.
  104.   --    return crc^0xffffffff;
  105.   --}
  106.  
  107.   repeat with i = 1 to lString.length
  108.     pCrc = bitXOR(bitShift(me, pCrc, 8), pCRCTable[bitXOR(bitAND(pCrc, 255),  charToNum(lString.char[i])) + 1])
  109.   end repeat
  110.  
  111. end mAppendToCRC
  112. ----------------------------------------------
  113. on mInitCRCTable me
  114.   --  // Call this function only once to initialize the CRC table.
  115.   --void CCRCfileDlg::Init_CRC32_Table()
  116.   --{// Called by OnInitDialog()
  117.   --
  118.   --    // This is the official polynomial used by CRC-32
  119.   --    // in PKZip, WinZip and Ethernet.
  120.   --    ULONG ulPolynomial = 0x04c11db7;
  121.   --
  122.   --    // 256 values representing ASCII character codes.
  123.   --    for(int i = 0; i <= 0xFF; i++)
  124.   --    {
  125.   --        crc32_table[i]=Reflect(i, 8) << 24;
  126.   --        for (int j = 0; j < 8; j++)
  127.   --            crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (1 << 31) ? ulPolynomial : 0);
  128.   --        crc32_table[i] = Reflect(crc32_table[i], 32);
  129.   --    }
  130.   --}
  131.  
  132.   lPolynomial = 79764919                                                 -- 0x04c11db7
  133.   pCRCTable = []
  134.  
  135.   repeat with i = 1 to 256                                               -- for(int i = 0; i <= 0xFF; i++)
  136.     pCRCTable[i] = bitShift(me, mReflectInt(me, (i - 1), 8), -24)        -- crc32_table[i] = Reflect(i, 8) << 24
  137.     repeat with j = 0 to 7                                               -- for (int j = 0; j < 8; j++)
  138.       if bitAND(pCRCTable[i], bitShift(me, 1, -31)) then                 -- if (crc32_table[i] & (1 << 31))
  139.         lTmp = lPolynomial                                               -- tmp = ulPolynomial;
  140.       else
  141.         lTmp = 0                                                         -- tmp = 0
  142.       end if
  143.       pCRCTable[i] = bitXOR(bitShift(me, pCRCTable[i], -1), lTmp)        -- crc32_table[i] = (crc32_table[i] << 1) ^ tmp
  144.     end repeat
  145.     pCRCTable[i] = mReflectInt(me, pCRCTable[i], 32)                     -- crc32_table[i] = Reflect(crc32_table[i], 32)
  146.   end repeat
  147.  
  148. end mInitCRCTable
  149. ----------------------------------------------
  150. on mReflectInt(me, lValue, lLen)
  151.   -- Reflection is a requirement for the official CRC-32 standard.
  152.   -- You can create CRCs without it, but they won't conform to the standard.
  153.   -- Base reflection lingo supplied by Robert Tweed
  154.  
  155.   -- Reflect a byte
  156.   --255 = 1 1 1 1 1 1 1 1     =>     1 1 1 1 1 1 1 1 = 255
  157.   --254 = 1 1 1 1 1 1 1 0     =>     0 1 1 1 1 1 1 1 = 127
  158.   --126 = 0 1 1 1 1 1 1 0     =>     0 1 1 1 1 1 1 0 = 126
  159.   --125 = 0 1 1 1 1 1 0 1     =>     1 0 1 1 1 1 1 0 = 190
  160.   --  4 = 0 0 0 0 0 1 0 0     =>     0 0 1 0 0 0 0 0 =  32
  161.  
  162.   lTmp = []
  163.   pBitShiftList = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, -2147483648]
  164.  
  165.   repeat with i = 1 to lLen
  166.     lTmp[i] = bitAnd(lValue , pBitShiftList[i])
  167.   end repeat
  168.  
  169.   lReflectValue = 0
  170.   lHLen = lLen / 2
  171.   repeat with i = 1 to lHLen
  172.     lReflectValue = integer(lReflectValue + lTmp[i] * pBitShiftList[lLen - ((i - 1) * 2)])
  173.   end repeat
  174.   repeat with i = (lHLen + 1) to lLen
  175.     lReflectValue = integer(lReflectValue + lTmp[i] / pBitShiftList[((i - lHLen) * 2)])
  176.   end repeat
  177.  
  178.   return lReflectValue
  179.  
  180. end mReflectInt
  181. ----------------------------------------------
  182. on bitShift(me, argVal, argAmount)
  183.   -- positive = right
  184.   -- Base bitShift lingo supplied by Jonas Beckeman
  185.  
  186.   if (argAmount > 0) then
  187.     if (argVal > 0) then argVal = argVal / pBitShiftList[argAmount+1]
  188.     else --means highest bit is set - remove it!
  189.       argVal = bitAnd(argVal, 2147483647)
  190.       argVal = argVal / pBitShiftList[argAmount+1]
  191.       argVal = argVal + pBitShiftList[32-argAmount]
  192.     end if
  193.   else
  194.     --remove upper bits
  195.     argVal = bitAnd(pUpperMasksList[-argAmount], argVal)
  196.     --then multiply
  197.     argVal = argVal * pBitShiftList[-argAmount+1]
  198.   end if
  199.  
  200.   return argVal
  201.  
  202. end bitShift
  203. ----------------------------------------------
  204. on mDispose me
  205.   -- Disposal function
  206.   pCRCTable = void
  207.   pCrc = void
  208.   pSeedCRC = void
  209.   pBitShiftList = void
  210.   pUpperMasksList = void
  211.  
  212. end mDispose
  213. ----------------------------------------------
[raw code]