semi合集-English.pdf - 第5929页
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 wh…

SEMI P39-0304
E2
© SEMI 2004 31
APPENDIX 1
CALCULATION OF VALIDATION SIGNATURES
NOTICE: The material in this appendix is an official part of SEMI P39 and was approved by full letter ballot
procedures on July 12, 2003.
A1-1 Sample CRC32 C-Language Source Code
The CRC32 must be calculated by processing the file contents as a single stream of bytes (CRC’s are order-
dependent). The CRC should be initialized by calling:
uint32 crc; /* the crc value */
crc32_init(&crc);
As each chunk of data in written into the file, one should call :
byte *buf; /* data written to output */
size_t len; /* # of bytes of data written to output */
crc32_add(&crc, buf, len);
When the END record is to be written, the CRC should be calculated using the
<id-value> and <validation-scheme> only.
The final value of the CRC32 should then be appended to the file as a 4-byte value in little-endian order.
#define CHG_ENDIAN32(a) { byte *p, b; \
p = (byte *) &(a); b=p[0]; p[0]=p[3]; p[3]=b; b=p[1]; p[1]=p[2]; p[2]=b; }
#ifdef BIG_ENDIAN_MACHINE
/* put calculated CRC in LITTLE_ENDIAN order (to align with byte ordering of the polynomial)
*/
CHG_ENDIAN32(crc);
#endif
_________________________________________________________________________________________________
_________________________________________________________________________________________________
/*
(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>
#define TEST
/********************/
/* basic data types */
/********************/
typedef unsigned char byte;
typedef unsigned int uint32;
/*************/
/* 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;}
/*
CRC polynomial as specified in ISO 3309 and ITU-T V.42
used in Ethernet, FDDI, cksum, etc
polynomial is x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10
+ x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0
if the leftmost bit is the msb, this is
binary 1 0000 0100 1100 0001 0001 1101 1011 0111

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);
}