//! This file is auto-generated by tools/update_crc_catalog.zig.

const builtin = @import("builtin");

pub const @"CRC-3/GSM" = Generic(u3, .{
    .polynomial = 0x3,
    .initial = 0x0,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x7,
});

pub const @"CRC-3/ROHC" = Generic(u3, .{
    .polynomial = 0x3,
    .initial = 0x7,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0,
});

pub const @"CRC-4/G-704" = Generic(u4, .{
    .polynomial = 0x3,
    .initial = 0x0,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0,
});

pub const @"CRC-4/INTERLAKEN" = Generic(u4, .{
    .polynomial = 0x3,
    .initial = 0xf,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xf,
});

pub const @"CRC-5/EPC-C1G2" = Generic(u5, .{
    .polynomial = 0x09,
    .initial = 0x09,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-5/G-704" = Generic(u5, .{
    .polynomial = 0x15,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-5/USB" = Generic(u5, .{
    .polynomial = 0x05,
    .initial = 0x1f,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x1f,
});

pub const @"CRC-6/CDMA2000-A" = Generic(u6, .{
    .polynomial = 0x27,
    .initial = 0x3f,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-6/CDMA2000-B" = Generic(u6, .{
    .polynomial = 0x07,
    .initial = 0x3f,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-6/DARC" = Generic(u6, .{
    .polynomial = 0x19,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-6/G-704" = Generic(u6, .{
    .polynomial = 0x03,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-6/GSM" = Generic(u6, .{
    .polynomial = 0x2f,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x3f,
});

pub const @"CRC-7/MMC" = Generic(u7, .{
    .polynomial = 0x09,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-7/ROHC" = Generic(u7, .{
    .polynomial = 0x4f,
    .initial = 0x7f,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-7/UMTS" = Generic(u7, .{
    .polynomial = 0x45,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/AUTOSAR" = Generic(u8, .{
    .polynomial = 0x2f,
    .initial = 0xff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xff,
});

pub const @"CRC-8/BLUETOOTH" = Generic(u8, .{
    .polynomial = 0xa7,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-8/CDMA2000" = Generic(u8, .{
    .polynomial = 0x9b,
    .initial = 0xff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/DARC" = Generic(u8, .{
    .polynomial = 0x39,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-8/DVB-S2" = Generic(u8, .{
    .polynomial = 0xd5,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/GSM-A" = Generic(u8, .{
    .polynomial = 0x1d,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/GSM-B" = Generic(u8, .{
    .polynomial = 0x49,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xff,
});

pub const @"CRC-8/HITAG" = Generic(u8, .{
    .polynomial = 0x1d,
    .initial = 0xff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/I-432-1" = Generic(u8, .{
    .polynomial = 0x07,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x55,
});

pub const @"CRC-8/I-CODE" = Generic(u8, .{
    .polynomial = 0x1d,
    .initial = 0xfd,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/LTE" = Generic(u8, .{
    .polynomial = 0x9b,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/MAXIM-DOW" = Generic(u8, .{
    .polynomial = 0x31,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-8/MIFARE-MAD" = Generic(u8, .{
    .polynomial = 0x1d,
    .initial = 0xc7,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/NRSC-5" = Generic(u8, .{
    .polynomial = 0x31,
    .initial = 0xff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/OPENSAFETY" = Generic(u8, .{
    .polynomial = 0x2f,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/ROHC" = Generic(u8, .{
    .polynomial = 0x07,
    .initial = 0xff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-8/SAE-J1850" = Generic(u8, .{
    .polynomial = 0x1d,
    .initial = 0xff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xff,
});

pub const @"CRC-8/SMBUS" = Generic(u8, .{
    .polynomial = 0x07,
    .initial = 0x00,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00,
});

pub const @"CRC-8/TECH-3250" = Generic(u8, .{
    .polynomial = 0x1d,
    .initial = 0xff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-8/WCDMA" = Generic(u8, .{
    .polynomial = 0x9b,
    .initial = 0x00,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00,
});

pub const @"CRC-10/ATM" = Generic(u10, .{
    .polynomial = 0x233,
    .initial = 0x000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000,
});

pub const @"CRC-10/CDMA2000" = Generic(u10, .{
    .polynomial = 0x3d9,
    .initial = 0x3ff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000,
});

pub const @"CRC-10/GSM" = Generic(u10, .{
    .polynomial = 0x175,
    .initial = 0x000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x3ff,
});

pub const @"CRC-11/FLEXRAY" = Generic(u11, .{
    .polynomial = 0x385,
    .initial = 0x01a,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000,
});

pub const @"CRC-11/UMTS" = Generic(u11, .{
    .polynomial = 0x307,
    .initial = 0x000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000,
});

pub const @"CRC-12/CDMA2000" = Generic(u12, .{
    .polynomial = 0xf13,
    .initial = 0xfff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000,
});

pub const @"CRC-12/DECT" = Generic(u12, .{
    .polynomial = 0x80f,
    .initial = 0x000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000,
});

pub const @"CRC-12/GSM" = Generic(u12, .{
    .polynomial = 0xd31,
    .initial = 0x000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xfff,
});

pub const @"CRC-12/UMTS" = Generic(u12, .{
    .polynomial = 0x80f,
    .initial = 0x000,
    .reflect_input = false,
    .reflect_output = true,
    .xor_output = 0x000,
});

pub const @"CRC-13/BBC" = Generic(u13, .{
    .polynomial = 0x1cf5,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-14/DARC" = Generic(u14, .{
    .polynomial = 0x0805,
    .initial = 0x0000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-14/GSM" = Generic(u14, .{
    .polynomial = 0x202d,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x3fff,
});

pub const @"CRC-15/CAN" = Generic(u15, .{
    .polynomial = 0x4599,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-15/MPT1327" = Generic(u15, .{
    .polynomial = 0x6815,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0001,
});

pub const @"CRC-16/ARC" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0x0000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/CDMA2000" = Generic(u16, .{
    .polynomial = 0xc867,
    .initial = 0xffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/CMS" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0xffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/DDS-110" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0x800d,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/DECT-R" = Generic(u16, .{
    .polynomial = 0x0589,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0001,
});

pub const @"CRC-16/DECT-X" = Generic(u16, .{
    .polynomial = 0x0589,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/DNP" = Generic(u16, .{
    .polynomial = 0x3d65,
    .initial = 0x0000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffff,
});

pub const @"CRC-16/EN-13757" = Generic(u16, .{
    .polynomial = 0x3d65,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffff,
});

pub const @"CRC-16/GENIBUS" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0xffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffff,
});

pub const @"CRC-16/GSM" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffff,
});

pub const @"CRC-16/IBM-3740" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0xffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/IBM-SDLC" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0xffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffff,
});

pub const @"CRC-16/ISO-IEC-14443-3-A" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0xc6c6,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/KERMIT" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0x0000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/LJ1200" = Generic(u16, .{
    .polynomial = 0x6f63,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/M17" = Generic(u16, .{
    .polynomial = 0x5935,
    .initial = 0xffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/MAXIM-DOW" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0x0000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffff,
});

pub const @"CRC-16/MCRF4XX" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0xffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/MODBUS" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0xffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/NRSC-5" = Generic(u16, .{
    .polynomial = 0x080b,
    .initial = 0xffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/OPENSAFETY-A" = Generic(u16, .{
    .polynomial = 0x5935,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/OPENSAFETY-B" = Generic(u16, .{
    .polynomial = 0x755b,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/PROFIBUS" = Generic(u16, .{
    .polynomial = 0x1dcf,
    .initial = 0xffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffff,
});

pub const @"CRC-16/RIELLO" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0xb2aa,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/SPI-FUJITSU" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0x1d0f,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/T10-DIF" = Generic(u16, .{
    .polynomial = 0x8bb7,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/TELEDISK" = Generic(u16, .{
    .polynomial = 0xa097,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/TMS37157" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0x89ec,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000,
});

pub const @"CRC-16/UMTS" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-16/USB" = Generic(u16, .{
    .polynomial = 0x8005,
    .initial = 0xffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffff,
});

pub const @"CRC-16/XMODEM" = Generic(u16, .{
    .polynomial = 0x1021,
    .initial = 0x0000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000,
});

pub const @"CRC-17/CAN-FD" = Generic(u17, .{
    .polynomial = 0x1685b,
    .initial = 0x00000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00000,
});

pub const @"CRC-21/CAN-FD" = Generic(u21, .{
    .polynomial = 0x102899,
    .initial = 0x000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000000,
});

pub const @"CRC-24/BLE" = Generic(u24, .{
    .polynomial = 0x00065b,
    .initial = 0x555555,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x000000,
});

pub const @"CRC-24/FLEXRAY-A" = Generic(u24, .{
    .polynomial = 0x5d6dcb,
    .initial = 0xfedcba,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000000,
});

pub const @"CRC-24/FLEXRAY-B" = Generic(u24, .{
    .polynomial = 0x5d6dcb,
    .initial = 0xabcdef,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000000,
});

pub const @"CRC-24/INTERLAKEN" = Generic(u24, .{
    .polynomial = 0x328b63,
    .initial = 0xffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffffff,
});

pub const @"CRC-24/LTE-A" = Generic(u24, .{
    .polynomial = 0x864cfb,
    .initial = 0x000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000000,
});

pub const @"CRC-24/LTE-B" = Generic(u24, .{
    .polynomial = 0x800063,
    .initial = 0x000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000000,
});

pub const @"CRC-24/OPENPGP" = Generic(u24, .{
    .polynomial = 0x864cfb,
    .initial = 0xb704ce,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x000000,
});

pub const @"CRC-24/OS-9" = Generic(u24, .{
    .polynomial = 0x800063,
    .initial = 0xffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffffff,
});

pub const @"CRC-30/CDMA" = Generic(u30, .{
    .polynomial = 0x2030b9c7,
    .initial = 0x3fffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x3fffffff,
});

pub const @"CRC-31/PHILIPS" = Generic(u31, .{
    .polynomial = 0x04c11db7,
    .initial = 0x7fffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x7fffffff,
});

pub const @"CRC-32/AIXM" = Generic(u32, .{
    .polynomial = 0x814141ab,
    .initial = 0x00000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00000000,
});

pub const @"CRC-32/AUTOSAR" = Generic(u32, .{
    .polynomial = 0xf4acfb13,
    .initial = 0xffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffffffff,
});

pub const @"CRC-32/BASE91-D" = Generic(u32, .{
    .polynomial = 0xa833982b,
    .initial = 0xffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffffffff,
});

pub const @"CRC-32/BZIP2" = Generic(u32, .{
    .polynomial = 0x04c11db7,
    .initial = 0xffffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffffffff,
});

pub const @"CRC-32/CD-ROM-EDC" = Generic(u32, .{
    .polynomial = 0x8001801b,
    .initial = 0x00000000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00000000,
});

pub const @"CRC-32/CKSUM" = Generic(u32, .{
    .polynomial = 0x04c11db7,
    .initial = 0x00000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffffffff,
});

pub const @"CRC-32/ISCSI" = if (builtin.cpu.hasAll(.x86, &.{ .@"64bit", .crc32 }))
    @import("crc/Crc32c.zig")
else
    Generic(u32, .{
        .polynomial = 0x1edc6f41,
        .initial = 0xffffffff,
        .reflect_input = true,
        .reflect_output = true,
        .xor_output = 0xffffffff,
    });

pub const @"CRC-32/ISO-HDLC" = Generic(u32, .{
    .polynomial = 0x04c11db7,
    .initial = 0xffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffffffff,
});

pub const @"CRC-32/JAMCRC" = Generic(u32, .{
    .polynomial = 0x04c11db7,
    .initial = 0xffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00000000,
});

pub const @"CRC-32/KOOPMAN" = Generic(u32, .{
    .polynomial = 0x741b8cd7,
    .initial = 0xffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffffffff,
});

pub const @"CRC-32/MEF" = Generic(u32, .{
    .polynomial = 0x741b8cd7,
    .initial = 0xffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x00000000,
});

pub const @"CRC-32/MPEG-2" = Generic(u32, .{
    .polynomial = 0x04c11db7,
    .initial = 0xffffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00000000,
});

pub const @"CRC-32/XFER" = Generic(u32, .{
    .polynomial = 0x000000af,
    .initial = 0x00000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x00000000,
});

pub const @"CRC-40/GSM" = Generic(u40, .{
    .polynomial = 0x0004820009,
    .initial = 0x0000000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffffffffff,
});

pub const @"CRC-64/ECMA-182" = Generic(u64, .{
    .polynomial = 0x42f0e1eba9ea3693,
    .initial = 0x0000000000000000,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0x0000000000000000,
});

pub const @"CRC-64/GO-ISO" = Generic(u64, .{
    .polynomial = 0x000000000000001b,
    .initial = 0xffffffffffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffffffffffffffff,
});

pub const @"CRC-64/MS" = Generic(u64, .{
    .polynomial = 0x259c84cba6426349,
    .initial = 0xffffffffffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000000000000000,
});

pub const @"CRC-64/REDIS" = Generic(u64, .{
    .polynomial = 0xad93d23594c935a9,
    .initial = 0x0000000000000000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x0000000000000000,
});

pub const @"CRC-64/WE" = Generic(u64, .{
    .polynomial = 0x42f0e1eba9ea3693,
    .initial = 0xffffffffffffffff,
    .reflect_input = false,
    .reflect_output = false,
    .xor_output = 0xffffffffffffffff,
});

pub const @"CRC-64/XZ" = Generic(u64, .{
    .polynomial = 0x42f0e1eba9ea3693,
    .initial = 0xffffffffffffffff,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0xffffffffffffffff,
});

pub const @"CRC-82/DARC" = Generic(u82, .{
    .polynomial = 0x0308c0111011401440411,
    .initial = 0x000000000000000000000,
    .reflect_input = true,
    .reflect_output = true,
    .xor_output = 0x000000000000000000000,
});

pub fn Algorithm(comptime W: type) type {
    return struct {
        polynomial: W,
        initial: W,
        reflect_input: bool,
        reflect_output: bool,
        xor_output: W,
    };
}

pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type {
    return struct {
        const Self = @This();
        const I = if (@bitSizeOf(W) < 8) u8 else W;
        const lookup_table = blk: {
            @setEvalBranchQuota(2500);
            const poly = reflect(algorithm.polynomial);
            var table: [256]I = undefined;
            for (&table, 0..) |*e, i| {
                var crc: I = i;
                if (algorithm.reflect_input) {
                    var j: usize = 0;
                    while (j < 8) : (j += 1) {
                        crc = (crc >> 1) ^ ((crc & 1) * poly);
                    }
                } else {
                    crc <<= @bitSizeOf(I) - 8;
                    var j: usize = 0;
                    while (j < 8) : (j += 1) {
                        crc = (crc << 1) ^ (((crc >> (@bitSizeOf(I) - 1)) & 1) * poly);
                    }
                }
                e.* = crc;
            }
            break :blk table;
        };

        crc: I,

        pub fn init() Self {
            const initial = reflect(algorithm.initial);
            return .{ .crc = initial };
        }

        inline fn tableEntry(index: I) I {
            const short: u8 = @truncate(index);
            return lookup_table[short];
        }

        pub fn update(self: *Self, bytes: []const u8) void {
            var i: usize = 0;
            if (@bitSizeOf(I) <= 8) {
                while (i < bytes.len) : (i += 1) {
                    self.crc = tableEntry(self.crc ^ bytes[i]);
                }
            } else if (algorithm.reflect_input) {
                while (i < bytes.len) : (i += 1) {
                    const table_index = self.crc ^ bytes[i];
                    self.crc = tableEntry(table_index) ^ (self.crc >> 8);
                }
            } else {
                while (i < bytes.len) : (i += 1) {
                    const table_index = (self.crc >> (@bitSizeOf(I) - 8)) ^ bytes[i];
                    self.crc = tableEntry(table_index) ^ (self.crc << 8);
                }
            }
        }

        pub fn final(self: Self) W {
            var c = self.crc;
            if (algorithm.reflect_input != algorithm.reflect_output) {
                c = @bitReverse(c);
            }
            if (!algorithm.reflect_output) {
                c >>= @bitSizeOf(I) - @bitSizeOf(W);
            }
            return @intCast(c ^ algorithm.xor_output);
        }

        pub fn hash(bytes: []const u8) W {
            var c = Self.init();
            c.update(bytes);
            return c.final();
        }

        fn reflect(x: I) I {
            const offset = @bitSizeOf(I) - @bitSizeOf(W);
            if (algorithm.reflect_input)
                return @bitReverse(x) >> offset
            else
                return x << offset;
        }
    };
}

test {
    _ = @import("crc/test.zig");
}
