namespace NpncbDiagnostic;

internal sealed class Crc32Accumulator
{
    private static readonly uint[] Table = BuildTable();
    private uint _state = 0xFFFF_FFFFu;

    public uint Value => _state ^ 0xFFFF_FFFFu;

    public void Update(byte value)
    {
        _state = Table[(byte)(_state ^ value)] ^ (_state >> 8);
    }

    private static uint[] BuildTable()
    {
        const uint polynomial = 0xEDB8_8320u;
        var table = new uint[256];

        for (int i = 0; i < table.Length; i++)
        {
            uint value = (uint)i;
            for (int bit = 0; bit < 8; bit++)
                value = (value & 1u) != 0 ? (value >> 1) ^ polynomial : value >> 1;
            table[i] = value;
        }

        return table;
    }
}
