semi合集-English.pdf - 第5930页
SEMI P39-0304 E2 © SEMI 2004 33 main(int argc, char **argv) { char *path; FILE *fptr; size_t len; byte buf[BUFFER_SZ]; uint32 crc; uint32 crc_to_file; switch (argc) { case 1 : path = "<stdin>"; fptr = std…

SEMI P39-0304
E2
© SEMI 2004 32
hex 1 0 4 c 1 1 d b 7
big order bit is implicit so we have
0x04c11db7
*/
#ifdef _ILP32
# define CRC32_POLY 0x04c11db7ul /* polynomial */
# define CRC32_CONSTANT 0x4b90b035ul /* constant which matches polynomial above */
# define LEFTMOST_BIT 0x80000000ul
# define ALL_BITS 0xfffffffful
#else
# define CRC32_POLY 0x04c11db7u /* polynomial */
# define CRC32_CONSTANT 0x4b90b035u /* constant which matches polynomial above */
# define LEFTMOST_BIT 0x80000000u
# define ALL_BITS 0xffffffffu
#endif
/* initialized to zero by the compiler */
static uint32 Crc32_tbl[256];
static void
crc32_tbl_load(void)
{
int i;
uint32 c;
int j;
/* initialize auxiliary table */
for (i = 0; i < 256; i++)
{
c = i << 24;
for (j = 0; j < BITS_IN_BYTE; j++)
c = c & LEFTMOST_BIT ? (c << 1) ^ CRC32_POLY : (c << 1);
Crc32_tbl[i] = c;
}
}
void
crc32_init(uint32 *crc)
{
/* initialize auxiliary table (if necessary) */
if (!Crc32_tbl[1])
crc32_tbl_load();
/* preload shift register, per CRC-32 spec */
*crc = ALL_BITS;
}
void
crc32_add(uint32 *crc,
byte *buf,
size_t len
)
{
uint32 val;
size_t i;
val = *crc;
val = ~val & ALL_BITS;
for (i = 0; i < len; i++)
val = (val >> 8) ^ Crc32_tbl[ (val ^ buf[i]) & 0xff];
val = ~val & ALL_BITS;
*crc = val;
}

SEMI P39-0304
E2
© SEMI 2004 33
main(int argc, char **argv)
{
char *path;
FILE *fptr;
size_t len;
byte buf[BUFFER_SZ];
uint32 crc;
uint32 crc_to_file;
switch (argc)
{
case 1 :
path = "<stdin>";
fptr = stdin; /* read from standard input */
break;
case 2 :
/* open input file (use the ’b’ flag to read as binary rather than text) */
path = argv[1];
if ( (fptr = fopen(path, "rb") ) == NULL)
{
fprintf(stderr, "\nerror opening %s (%s)\n", path, strerror(errno) );
exit(1);
}
break;
default :
fprintf(stderr, "\nusage: %s pathname\n", argv[0]);
fprintf(stderr, " -or-");
fprintf(stderr, "\n %s < pathname\n", argv[0]);
exit(1);
}
/* initialize */
crc32_init(&crc);
/* calculate crc for all data in file */
while (len = (fread(buf, 1, BUFFER_SZ, fptr) ) )
crc32_add(&crc, buf, len);
if (!feof(fptr) )
{
fprintf(stderr, "\nerror reading %s (%s)\n", path, strerror(errno) );
if (fptr != stdin)
fclose(fptr);
exit(1);
}
if (fptr != stdin)
fclose(fptr);
crc_to_file = crc;
/* ensure CRC32 is written to OASIS file in LITTLE_ENDIAN byte order */
#ifdef BIG_ENDIAN_MACHINE
CHG_ENDIAN(crc_to_file);
#endif
#ifdef TEST
/* this is the crc value that should be the last 4 bytes in the file */
printf("crc_to_file = 0x%08x\n", crc_to_file);
/* assume the CRC32 value crc_to_file was appended to the end of the Oasis file */
/* add the CRC32 (in LITTLE_ENDIAN order) to the data stream and continue CRC calculation */
crc32_add(&crc, (byte *) &crc_to_file, size of(crc_to_file) );
#endif
printf("crc_constant (should be 0x%08x) = 0x%08x\n", CRC32_CONSTANT, crc);
exit(0);
}

SEMI P39-0304
E2
© SEMI 2004 34
A1-2 Sample CHECKSUM32 C-Language Source Code
/*
(c) Copyright 2003 SEMI
no warranty, express or implied
not liable for damages resulting from or in connection with use of this software
*/
#include <stdio.h>
#include <errno.h>
/********************/
/* basic data types */
/********************/
typedef unsigned char byte;
typedef unsigned int uint32;
#ifdef _ILP32
typedef unsigned long long uint64;
#else
typedef unsigned long uint64;
#endif
/*************/
/* constants */
/*************/
#define BUFFER_SZ 8 * 1024
#define BITS_IN_BYTE 8
/**********/
/* macros */
/**********/
#define CHG_ENDIAN(a) {byte *p, t; p=(byte *)&(a); t=p[0]; p[0]=p[3]; p[3]=t; t=p[1]; p[1]=p[2];
p[2]=t;}
void
checksum_init(uint32 *chksum)
{
*chksum = 0;
}
void
checksum_add(uint32 *chksum,
byte *buf,
size_t len
)
{
uint64 val; /* could be a uint32, but overflow handling is undefined */
size_t i;
val = (uint64) *chksum;
for (i = 0; i < len; i++)
{
val += buf[i]; /* sum */
val &= 0xffffffff; /* limit to 32 bits */
}
*chksum = (uint32) val;
}
main(int argc, char **argv)
{
char *path;
FILE *fptr;
size_t len;
byte buf[BUFFER_SZ];
uint32 chksum;
uint32 chksum_to_file;
switch (argc)