/* crc-generate-table.c -- cyclic redundancy check table generator Copyright (C) 2024-2025 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Written by Sam Russell. */ #include #include /* * The following function was extracted from RFC 1952 by Sam * Russell. It was modified to remove the reference to the * crc_table_computed flag, to extend it to accept a variable number * of bits (described below), and reformatted to follow GNU * formatting guidelines. * * make_crc_table() takes a number of bits and generates a lookup * table for the CRC32 algorithm. Usage is as follows: * * make_crc_table(8) : generate for CRC32(0x00) to CRC32(0xFF) * make_crc_table(16) : generate for CRC32(0x0000) to CRC32 (0xFF00) * in increments of 0x100 * * This is used for the Sarwate algorithm specified in RFC 1952 * which uses a single lookup table of make_crc_table(8), and for * the slice-by-8 algorithm which uses 8 tables from in 8-bit * increments from make_crc_table(8) to make_crc_table(64) */ unsigned long crc_table[256]; static void make_crc_table (int bits) { unsigned long c; int n, k; for (n = 0; n < 256; n++) { c = (unsigned long) n; for (k = 0; k < bits; k++) { if (c & 1) c = 0xedb88320L ^ (c >> 1); else c = c >> 1; } crc_table[n] = c; } } static void print_crc_table (FILE * stream, int bits) { make_crc_table (bits); fprintf (stream, " {"); for (int i = 0; i < 256; i++) { if ((i % 6) == 0) fprintf (stream, "\n "); if (i != 255) fprintf (stream, " 0x%08lX,", crc_table[i]); else fprintf (stream, " 0x%08lX\n", crc_table[i]); } fprintf (stream, " }"); } static void print_header (FILE * stream) { fprintf (stream, "/* Slice-by-8 lookup tables */\n"); fprintf (stream, "static const uint32_t crc32_sliceby8_table[][256] = {\n"); for (int i = 8; i <= 64; i += 8) { print_crc_table (stream, i); if (i < 64) fprintf (stream, ","); fprintf (stream, "\n"); } fprintf (stream, "};\n"); } static void print_copyright_notice (FILE * stream) { fprintf (stream, "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n"); fprintf (stream, "/* crc.c -- cyclic redundancy checks\n"); fprintf (stream, "Copyright (C) 2005-2006, 2009-2025 Free Software Foundation, Inc.\n"); fprintf (stream, "\n"); fprintf (stream, "This file is free software: you can redistribute it and/or modify\n"); fprintf (stream, "it under the terms of the GNU Lesser General Public License as\n"); fprintf (stream, "published by the Free Software Foundation, either version 3 of the\n"); fprintf (stream, "License, or (at your option) any later version.\n"); fprintf (stream, "\n"); fprintf (stream, "This file is distributed in the hope that it will be useful,\n"); fprintf (stream, "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); fprintf (stream, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); fprintf (stream, "GNU Lesser General Public License for more details.\n"); fprintf (stream, "\n"); fprintf (stream, "You should have received a copy of the GNU Lesser General Public License\n"); fprintf (stream, "along with this program. If not, see . */\n\n"); } int main (int argc, char *argv[]) { if (argc != 2) { fprintf (stderr, " Usage: %s crc-sliceby8.h\n", argv[0]); exit (1); } const char *filename = argv[1]; FILE *stream = fopen (filename, "w"); if (stream == NULL) { fprintf (stderr, "cannot open '%s' for writing\n", filename); exit (1); } print_copyright_notice (stream); print_header (stream); if (ferror (stream) || fclose (stream)) { fprintf (stderr, "error writing to '%s'\n", filename); exit (1); } return 0; }