/// <summary>Retrieves a standard set of CRC parameters.</summary> /// <param name="standard">The name of the standard parameter set to retrieve.</param> /// <returns>The CRC Parameters for the given standard.</returns> public static CRCParameters GetParameters(CRCStandard standard) { CRCParameters param = null; switch (standard) { case CRCStandard.CRC8: param = new CRCParameters(8, 0x07, 0, 0, false); break; case CRCStandard.CRC16_IBM: param = new CRCParameters(16, 0x8005, 0, 0, false); break; case CRCStandard.CRC16_CCITT: param = new CRCParameters(16, 0x1021, 0xFFFF, 0, false); break; case CRCStandard.CRC16_ARC: param = new CRCParameters(16, 0x8005, 0, 0, true); break; case CRCStandard.CRC16_XMODEM: param = new CRCParameters(16, 0x8408, 0, 0, true); break; case CRCStandard.CRC16_ZMODEM: param = new CRCParameters(16, 0x1021, 0, 0, false); break; case CRCStandard.CRC24: param = new CRCParameters(24, 0x1864CFB, 0xB704CE, 0, false); break; case CRCStandard.CRC32: param = new CRCParameters(32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true); break; case CRCStandard.CRC32_JAMCRC: param = new CRCParameters(32, 0x04C11DB7, 0xFFFFFFFF, 0, true); break; case CRCStandard.CRC32_BZIP2: param = new CRCParameters(32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, false); break; case CRCStandard.CRC64_ISO: param = new CRCParameters(64, 0x000000000000001B, 0, 0, true); break; case CRCStandard.CRC64_ECMA: param = new CRCParameters(64, 0x42F0E1EBA9EA3693, -1, -1, false); break; } return(param); }
/// <summary>Build the CRC lookup table for a given polynomial.</summary> static private void BuildLookup(CRCParameters param) { if (lookupTables.Contains(param)) { // No sense in creating the table twice. return; } var table = new long[256]; var topBit = (long)1 << (param.Order - 1); long widthMask = (((1 << (param.Order - 1)) - 1) << 1) | 1; // Build the table. for (var i = 0; i < table.Length; i++) { table[i] = i; if (param.ReflectInput) { table[i] = Reflect(i, 8); } table[i] = table[i] << (param.Order - 8); for (var j = 0; j < 8; j++) { if ((table[i] & topBit) != 0) { table[i] = (table[i] << 1) ^ param.Polynomial; } else { table[i] <<= 1; } } if (param.ReflectInput) { table[i] = Reflect(table[i], param.Order); } table[i] &= widthMask; } // Add the new lookup table. lookupTables.Add(param, table); }
/// <summary>Initializes a new instance of the CRC class.</summary> /// <param name="param">The parameters to utilize in the CRC calculation.</param> public CRC(CRCParameters param) { lock (this) { if (param == null) { throw new ArgumentNullException("param", "The CRCParameters cannot be null."); } parameters = param; HashSizeValue = param.Order; BuildLookup(param); lookup = (long[])lookupTables[param]; if (param.Order == 64) { registerMask = 0x00FFFFFFFFFFFFFF; } else { registerMask = (long)(Math.Pow(2, (param.Order - 8)) - 1); } Initialize(); } }
// Pre-build the more popular lookup tables. static CRC() { lookupTables = new Hashtable(); BuildLookup(CRCParameters.GetParameters(CRCStandard.CRC32)); }