예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Crc"/> class.
        /// </summary>
        /// <param name="parameters"></param>
        private Crc([NotNull] CrcParameters parameters)
        {
            Check.NotNull(parameters, nameof(parameters));

            _parameters = parameters;
            LookupTable = GetOrCreateLookupTable(parameters);
        }
예제 #2
0
        private static ulong[] GetOrCreateLookupTable(CrcParameters p)
        {
            int refIn  = p.ReflectIn ? 1 : 0;
            int refOut = p.ReflectOut ? 1 : 0;

            var cacheKey = $"{p.Width}:{p.Polynomial}{p.InitialValue}{p.XorOutValue}{refIn}{refOut}";

            return(LookupTableCache.GetOrAdd(
                       cacheKey,
                       t =>
            {
                var lookupTable = new ulong[256];
                var topBit = (ulong)1 << (p.Width - 1);

                // Calculate lookup table
                for (var i = 0; i < lookupTable.Length; i++)
                {
                    var r = (ulong)i;
                    if (p.ReflectIn)
                    {
                        r = ReflectBits(r, p.Width);
                    }
                    else if (p.Width > 8)
                    {
                        r <<= p.Width - 8;
                    }

                    //var r = (ulong)inByte << (width - 8);
                    for (var j = 0; j < 8; j++)
                    {
                        r = (r & topBit) != 0 ? (r << 1) ^ p.Polynomial : r << 1;
                    }

                    if (p.ReflectIn)
                    {
                        r = ReflectBits(r, p.Width);
                    }

                    lookupTable[i] = r & (ulong.MaxValue >> (64 - p.Width));
                }

                // Done
                return lookupTable;
            }
                       ));
        }