refactored crc32.h
This commit is contained in:
parent
4f7b15f0f2
commit
29529cd8f2
4 changed files with 105 additions and 146 deletions
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
PROGRAM = crc32
|
PROGRAM = crc32
|
||||||
.PHONY: all clean install
|
.PHONY: all clean install
|
||||||
FILES = main.c args.c
|
FILES = main.c args.c crc32.c
|
||||||
|
|
||||||
CFLAGS += -Wall -Werror -ansi -pedantic
|
CFLAGS += -Wall -Werror -ansi -pedantic
|
||||||
LDFLAGS +=
|
LDFLAGS +=
|
||||||
|
|
98
crc32.c
Normal file
98
crc32.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/* Copyright (C) 2012 Connor Olding
|
||||||
|
*
|
||||||
|
* This program is licensed under the terms of the MIT License, and
|
||||||
|
* is distributed without any warranty. You should have received a
|
||||||
|
* copy of the license along with this program; see the file LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
|
#include "crc32.h"
|
||||||
|
|
||||||
|
int crc_big_endian = 0;
|
||||||
|
ulong crc_polynomial = 0x04C11DB7;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
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 reflected = 0;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4 * 8; i++) {
|
||||||
|
reflected <<= 1;
|
||||||
|
reflected |= input & 1;
|
||||||
|
input >>= 1;
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crc_fill_big_endian_table()
|
||||||
|
{
|
||||||
|
const ulong lsb = 1 << 31; /* least significant bit */
|
||||||
|
ulong c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (c = 0; c < TABLE_SIZE; c++) {
|
||||||
|
crc_be_table[c] = c << 24;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (crc_be_table[c] & lsb) {
|
||||||
|
crc_be_table[c] <<= 1;
|
||||||
|
crc_be_table[c] ^= crc_polynomial;
|
||||||
|
} else {
|
||||||
|
crc_be_table[c] <<= 1;
|
||||||
|
}
|
||||||
|
crc_be_table[c] &= 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crc_fill_little_endian_table()
|
||||||
|
{
|
||||||
|
const ulong lsb = 1; /* least significant bit */
|
||||||
|
const ulong reflected = crc_reflect(crc_polynomial);
|
||||||
|
ulong c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (c = 0; c < TABLE_SIZE; c++) {
|
||||||
|
crc_le_table[c] = c;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (crc_le_table[c] & lsb) {
|
||||||
|
crc_le_table[c] >>= 1;
|
||||||
|
crc_le_table[c] ^= reflected;
|
||||||
|
} else {
|
||||||
|
crc_le_table[c] >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crc_fill_tables_once()
|
||||||
|
{
|
||||||
|
static char filled = 0;
|
||||||
|
if (crc_big_endian && !(filled & 1)) {
|
||||||
|
crc_fill_big_endian_table();
|
||||||
|
filled |= 1;
|
||||||
|
} else if (!crc_big_endian && !(filled & 2)) {
|
||||||
|
crc_fill_little_endian_table();
|
||||||
|
filled |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void crc_cycle(ulong *remainder, char c)
|
||||||
|
{
|
||||||
|
crc_fill_tables_once();
|
||||||
|
if (crc_big_endian) {
|
||||||
|
const ulong byte = crc_be_table[((*remainder) >> 24) ^ c];
|
||||||
|
*remainder = ((*remainder) << 8) ^ byte;
|
||||||
|
*remainder &= 0xFFFFFFFF;
|
||||||
|
} else {
|
||||||
|
const ulong byte = crc_le_table[((*remainder) ^ c) & 0xFF];
|
||||||
|
*remainder = ((*remainder) >> 8) ^ byte;
|
||||||
|
}
|
||||||
|
}
|
144
crc32.h
144
crc32.h
|
@ -5,149 +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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CRC32_H_
|
int crc_big_endian;
|
||||||
#define CRC32_H_
|
ulong crc_polynomial;
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* interface */
|
|
||||||
|
|
||||||
typedef unsigned long ulong;
|
|
||||||
|
|
||||||
void crc_cycle(ulong *remainder, char c);
|
void crc_cycle(ulong *remainder, char c);
|
||||||
ulong crc_reflect(ulong input);
|
ulong crc_reflect(ulong input);
|
||||||
|
|
||||||
void crc_set_big_endian();
|
|
||||||
void crc_set_little_endian();
|
|
||||||
void crc_set_polynomial(ulong p);
|
|
||||||
|
|
||||||
/* implementation */
|
|
||||||
|
|
||||||
static char crc_big_endian = 0;
|
|
||||||
static const int crc_table_size = 0x100;
|
|
||||||
static ulong *crc_be_table = NULL; /* big endian */
|
|
||||||
static ulong *crc_le_table = NULL; /* little endian */
|
|
||||||
static ulong crc_polynomial = 0x04C11DB7;
|
|
||||||
|
|
||||||
ulong crc_reflect(ulong input)
|
|
||||||
{
|
|
||||||
ulong reflected = 0;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4 * 8; i++) {
|
|
||||||
reflected <<= 1;
|
|
||||||
reflected |= input & 1;
|
|
||||||
input >>= 1;
|
|
||||||
}
|
|
||||||
return reflected;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ulong *crc_alloc(size_t size)
|
|
||||||
{
|
|
||||||
ulong *p = (ulong*) malloc(size * sizeof(ulong));
|
|
||||||
if (p == NULL)
|
|
||||||
exit(1);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void crc_allocate_tables_once()
|
|
||||||
{
|
|
||||||
static char allocated = 0;
|
|
||||||
if (crc_big_endian && !(allocated & 1)) {
|
|
||||||
crc_be_table = crc_alloc(crc_table_size);
|
|
||||||
allocated |= 1;
|
|
||||||
} else if (!crc_big_endian && !(allocated & 2)) {
|
|
||||||
crc_le_table = crc_alloc(crc_table_size);
|
|
||||||
allocated |= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void crc_fill_big_endian_table()
|
|
||||||
{
|
|
||||||
const ulong least_significant_bit = 1 << 31;
|
|
||||||
ulong c;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
crc_allocate_tables_once();
|
|
||||||
|
|
||||||
for (c = 0; c < crc_table_size; c++) {
|
|
||||||
crc_be_table[c] = c << 24;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (crc_be_table[c] & least_significant_bit) {
|
|
||||||
crc_be_table[c] <<= 1;
|
|
||||||
crc_be_table[c] ^= crc_polynomial;
|
|
||||||
} else {
|
|
||||||
crc_be_table[c] <<= 1;
|
|
||||||
}
|
|
||||||
crc_be_table[c] &= 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void crc_fill_little_endian_table()
|
|
||||||
{
|
|
||||||
const ulong least_significant_bit = 1;
|
|
||||||
const ulong reflected_polynomial = crc_reflect(crc_polynomial);
|
|
||||||
ulong c;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
crc_allocate_tables_once();
|
|
||||||
/* printf("p: %08X\n", (int)reflected_polynomial); */
|
|
||||||
|
|
||||||
for (c = 0; c < crc_table_size; c++) {
|
|
||||||
crc_le_table[c] = c;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (crc_le_table[c] & least_significant_bit) {
|
|
||||||
crc_le_table[c] >>= 1;
|
|
||||||
crc_le_table[c] ^= reflected_polynomial;
|
|
||||||
} else {
|
|
||||||
crc_le_table[c] >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void crc_fill_tables_once()
|
|
||||||
{
|
|
||||||
static char filled = 0;
|
|
||||||
if (crc_big_endian && !(filled & 1)) {
|
|
||||||
crc_fill_big_endian_table();
|
|
||||||
filled |= 1;
|
|
||||||
} else if (!crc_big_endian && !(filled & 2)) {
|
|
||||||
crc_fill_little_endian_table();
|
|
||||||
filled |= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void crc_set_big_endian()
|
|
||||||
{
|
|
||||||
crc_big_endian = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void crc_set_little_endian()
|
|
||||||
{
|
|
||||||
crc_big_endian = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void crc_set_polynomial(ulong p)
|
|
||||||
{
|
|
||||||
crc_polynomial = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void crc_cycle(ulong *remainder, char c)
|
|
||||||
{
|
|
||||||
crc_fill_tables_once();
|
|
||||||
if (crc_big_endian) {
|
|
||||||
const ulong newByte = crc_be_table[((*remainder) >> 24) ^ c];
|
|
||||||
/* printf("%08X00 ^ %08X =\n",
|
|
||||||
(int)(*remainder), (int)newByte); */
|
|
||||||
*remainder = ((*remainder) << 8) ^ newByte;
|
|
||||||
*remainder &= 0xFFFFFFFF;
|
|
||||||
} else {
|
|
||||||
const ulong newByte = crc_le_table[((*remainder) ^ c) & 0xFF];
|
|
||||||
/* printf(" %08X ^ %08X =\n",
|
|
||||||
(int)((*remainder) >> 8), (int)newByte); */
|
|
||||||
*remainder = ((*remainder) >> 8) ^ newByte;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
7
main.c
7
main.c
|
@ -9,6 +9,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
|
@ -65,7 +67,7 @@ static void handle_flag(char flag, char *(*nextarg)())
|
||||||
printf(help2);
|
printf(help2);
|
||||||
exit(0);
|
exit(0);
|
||||||
case 'e':
|
case 'e':
|
||||||
crc_set_big_endian();
|
crc_big_endian = 1;
|
||||||
return;
|
return;
|
||||||
case 'b':
|
case 'b':
|
||||||
print_binary = 1;
|
print_binary = 1;
|
||||||
|
@ -85,7 +87,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_set_polynomial(strtoul(next, NULL, 0));
|
crc_polynomial = strtoul(next, NULL, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unknown flag: -%c\n", flag);
|
fprintf(stderr, "Unknown flag: -%c\n", flag);
|
||||||
|
@ -147,7 +149,6 @@ static void print_crc(ulong remainder)
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
string_node *n;
|
string_node *n;
|
||||||
crc_set_little_endian();
|
|
||||||
args_parse(argc, argv, handle_flag, add_input);
|
args_parse(argc, argv, handle_flag, add_input);
|
||||||
|
|
||||||
if (!input_node) {
|
if (!input_node) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue