offload crc table handling

This commit is contained in:
Connor Olding 2012-08-05 19:58:43 -07:00
parent a215f38d6d
commit 4e0f09e57f
3 changed files with 26 additions and 38 deletions

45
crc32.c
View File

@ -5,10 +5,7 @@
* copy of the license along with this program; see the file LICENSE. * copy of the license along with this program; see the file LICENSE.
*/ */
#include <stdlib.h>
typedef unsigned long ulong; typedef unsigned long ulong;
#include "crc32.h" #include "crc32.h"
int crc_big_endian = 0; int crc_big_endian = 0;
@ -17,8 +14,6 @@ ulong crc_polynomial = 0x04C11DB7;
enum { enum {
TABLE_SIZE = 0x100 TABLE_SIZE = 0x100
}; };
static ulong crc_be_table[TABLE_SIZE]; /* big endian */
static ulong crc_le_table[TABLE_SIZE]; /* little endian */
ulong crc_reflect(ulong input) ulong crc_reflect(ulong input)
{ {
@ -32,47 +27,35 @@ ulong crc_reflect(ulong input)
return reflected; return reflected;
} }
static void crc_fill_table(int big) /* TODO: test returning array */
void crc_fill_table(ulong *table, int big, ulong polynomial)
{ {
ulong lsb = (big) ? 1 << 31 : 1; /* least significant bit */ ulong lsb = (big) ? 1 << 31 : 1; /* least significant bit */
ulong poly = (big) ? crc_polynomial : crc_reflect(crc_polynomial); ulong poly = (big) ? polynomial : crc_reflect(polynomial);
ulong *tc = (big) ? crc_be_table : crc_le_table;
int c, i; int c, i;
for (c = 0; c < TABLE_SIZE; c++, tc++) { for (c = 0; c < TABLE_SIZE; c++, table++) {
*tc = (big) ? c << 24 : c; *table = (big) ? c << 24 : c;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (*tc & lsb) { if (*table & lsb) {
*tc = (big) ? *tc << 1 : *tc >> 1; *table = (big) ? *table << 1 : *table >> 1;
*tc ^= poly; *table ^= poly;
} else { } else {
*tc = (big) ? *tc << 1 : *tc >> 1; *table = (big) ? *table << 1 : *table >> 1;
} }
*tc &= 0xFFFFFFFF; *table &= 0xFFFFFFFF;
} }
} }
} }
void crc_be_cycle(ulong *remainder, char c) void crc_be_cycle(ulong *table, ulong *remainder, char c)
{ {
static char filled = 0; ulong byte = table[((*remainder) >> 24) ^ c];
ulong byte;
if (!filled) {
crc_fill_table(1);
filled = 1;
}
byte = crc_be_table[((*remainder) >> 24) ^ c];
*remainder = (((*remainder) << 8) ^ byte) & 0xFFFFFFFF; *remainder = (((*remainder) << 8) ^ byte) & 0xFFFFFFFF;
} }
void crc_le_cycle(ulong *remainder, char c) void crc_le_cycle(ulong *table, ulong *remainder, char c)
{ {
static char filled = 0; ulong byte = table[((*remainder) ^ c) & 0xFF];
ulong byte;
if (!filled) {
crc_fill_table(0);
filled = 1;
}
byte = crc_le_table[((*remainder) ^ c) & 0xFF];
*remainder = ((*remainder) >> 8) ^ byte; *remainder = ((*remainder) >> 8) ^ byte;
} }

View File

@ -5,8 +5,9 @@
* copy of the license along with this program; see the file LICENSE. * copy of the license along with this program; see the file LICENSE.
*/ */
ulong crc_polynomial; enum { CRC_TABLE_SIZE = 0x100 };
void crc_be_cycle(ulong *remainder, char c); void crc_fill_table(ulong *table, int big, ulong polynomial);
void crc_le_cycle(ulong *remainder, char c); void crc_be_cycle(ulong *table, ulong *remainder, char c);
void crc_le_cycle(ulong *table, ulong *remainder, char c);
ulong crc_reflect(ulong input); ulong crc_reflect(ulong input);

12
main.c
View File

@ -35,6 +35,7 @@ static string_node *input_node = NULL;
static ulong starting = 0xFFFFFFFF; static ulong starting = 0xFFFFFFFF;
static char big_endian = 0; static char big_endian = 0;
static ulong polynomial = 0x04C11DB7;
static char print_binary = 0; static char print_binary = 0;
static char xor_output = 1; static char xor_output = 1;
static char reflect_output = 0; static char reflect_output = 0;
@ -90,7 +91,7 @@ static void handle_flag(char flag, char *(*nextarg)())
break; break;
case 'p': case 'p':
next = check_next(flag, nextarg()); next = check_next(flag, nextarg());
crc_polynomial = strtoul(next, NULL, 0); polynomial = strtoul(next, NULL, 0);
break; break;
default: default:
fprintf(stderr, "Unknown flag: -%c\n", flag); fprintf(stderr, "Unknown flag: -%c\n", flag);
@ -130,9 +131,12 @@ static FILE *open_stream(char *filename)
static ulong cycle_file(FILE *stream) static ulong cycle_file(FILE *stream)
{ {
ulong remainder = starting; ulong remainder = starting;
void (*cycle)(ulong*, char) = (big_endian) ? crc_be_cycle : crc_le_cycle; void (*cycle)(ulong*, ulong*, char) =
(big_endian) ? crc_be_cycle : crc_le_cycle;
ulong table[CRC_TABLE_SIZE];
int i, len; int i, len;
crc_fill_table(table, big_endian, polynomial);
do { do {
len = fread(buff, 1, BUFFER_SIZE, stream); len = fread(buff, 1, BUFFER_SIZE, stream);
if (ferror(stream)) { if (ferror(stream)) {
@ -141,7 +145,7 @@ static ulong cycle_file(FILE *stream)
} }
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
cycle(&remainder, buff[i]); cycle(table, &remainder, buff[i]);
} while (!feof(stream)); } while (!feof(stream));
if (xor_output) if (xor_output)