/// <summary> /// Calculate the CRC-32 of a memory pointer. /// </summary> /// <param name="data">Pointer containing the bytes to calculate.</param> /// <param name="length">Specify the length, in bytes, of the data to be checked.</param> /// <param name="crc">Input CRC value for ongoing calculations (default is FFFFFFFFh).</param> /// <param name="bufflen">Specify the size, in bytes, of the marshaling buffer to be used (default is 1k).</param> /// <returns>A 32-bit unsigned integer representing the calculated CRC.</returns> /// <remarks></remarks> public static uint Calculate(IntPtr data, IntPtr length, uint crc = 0xFFFFFFFFU, int bufflen = 1024) { uint CalculateRet = default; if (length.ToInt64() <= 0L) { throw new ArgumentOutOfRangeException("length", "length must be a positive number."); } if (data == IntPtr.Zero) { throw new ArgumentNullException("data", "data cannot be equal to null."); } // ' our working marshal buffer will be 1k, this is a good compromise between eating up memory and efficiency. int blen = bufflen; byte[] b; var mm = new MemPtr(data); long i; long l = length.ToInt64(); long c = l - 1L; int e; int j; b = new byte[blen]; var loopTo = c; for (i = 0L; (long)blen >= 0 ? i <= loopTo : i >= loopTo; i += blen) { if (l - i > blen) { e = blen; } else { e = (int)(l - i); } mm.GrabBytes((IntPtr)i, e, ref b); e -= 1; var loopTo1 = e; for (j = 0; j <= loopTo1; j++) { crc = Crc32Table[(int)((crc ^ b[j]) & 0xFFL)] ^ crc >> 8; } } CalculateRet = crc ^ 0xFFFFFFFFU; return(CalculateRet); }