client: fix mix of spaces & tabs
This commit is contained in:
@@ -42,46 +42,46 @@ int bmpsub;
|
||||
|
||||
void
|
||||
setbmp(void) {
|
||||
/* Initialise BMP_BIT and BMP_SUB for the local architecture. */
|
||||
bmp_t bmpmax = ~(bmp_t) 0;
|
||||
/* Initialise BMP_BIT and BMP_SUB for the local architecture. */
|
||||
bmp_t bmpmax = ~(bmp_t) 0;
|
||||
|
||||
bmpbit = 0; bmpsub = 1;
|
||||
bmpbit = 0; bmpsub = 1;
|
||||
|
||||
while(bmpmax) {
|
||||
bmpmax <<= 1;
|
||||
++bmpbit;
|
||||
}
|
||||
while(bmpmax) {
|
||||
bmpmax <<= 1;
|
||||
++bmpbit;
|
||||
}
|
||||
|
||||
while((bmpsub | (bmpsub - 1)) < bmpbit - 1)
|
||||
bmpsub <<= 1;
|
||||
while((bmpsub | (bmpsub - 1)) < bmpbit - 1)
|
||||
bmpsub <<= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BMPTST
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
/* check the compile-time bitmap width is correct, otherwise
|
||||
* searches run forever. */
|
||||
/* check the compile-time bitmap width is correct, otherwise
|
||||
* searches run forever. */
|
||||
# if BMP_BIT > 0
|
||||
setbmp();
|
||||
if(BMP_BIT != bmpbit || BMP_SUB != bmpsub) {
|
||||
fprintf(stderr,"reveng: configuration fault. Update "
|
||||
"config.h with these definitions and "
|
||||
"recompile:\n"
|
||||
"\t#define BMP_BIT %d\n"
|
||||
"\t#define BMP_SUB %d\n",
|
||||
bmpbit, bmpsub);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
setbmp();
|
||||
if(BMP_BIT != bmpbit || BMP_SUB != bmpsub) {
|
||||
fprintf(stderr,"reveng: configuration fault. Update "
|
||||
"config.h with these definitions and "
|
||||
"recompile:\n"
|
||||
"\t#define BMP_BIT %d\n"
|
||||
"\t#define BMP_SUB %d\n",
|
||||
bmpbit, bmpsub);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
# endif /* BMP_BIT > 0 */
|
||||
/* check the bitmap constant macro */
|
||||
if(~(bmp_t) 0 != ~BMP_C(0)) {
|
||||
fprintf(stderr, "reveng: configuration fault. Edit "
|
||||
"the definition of BMP_C() in config.h to "
|
||||
"match BMP_T and recompile.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
/* check the bitmap constant macro */
|
||||
if(~(bmp_t) 0 != ~BMP_C(0)) {
|
||||
fprintf(stderr, "reveng: configuration fault. Edit "
|
||||
"the definition of BMP_C() in config.h to "
|
||||
"match BMP_T and recompile.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#endif /* BMPTST */
|
||||
|
||||
1004
client/reveng/cli.c
1004
client/reveng/cli.c
File diff suppressed because it is too large
Load Diff
@@ -26,9 +26,9 @@
|
||||
#define CONFIG_H 1
|
||||
|
||||
/*****************************************
|
||||
* *
|
||||
* *
|
||||
* Start of user configuration options *
|
||||
* *
|
||||
* *
|
||||
*****************************************/
|
||||
|
||||
/* A type to contain polynomial coefficient bitmaps.
|
||||
@@ -85,9 +85,9 @@
|
||||
#define BMP_SUB 16
|
||||
|
||||
/*****************************************
|
||||
* *
|
||||
* *
|
||||
* End of user configuration options *
|
||||
* *
|
||||
* *
|
||||
*****************************************/
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
||||
@@ -37,45 +37,45 @@ int getopt(int argc, char *argv[], const char *optstring)
|
||||
char *str;
|
||||
|
||||
if (pos == 0) {
|
||||
if ((optind >= argc) || (*argv[optind] != '-'))
|
||||
return EOF;
|
||||
pos = 1;
|
||||
if (argv[optind][pos] == '\0')
|
||||
return EOF;
|
||||
if ((optind >= argc) || (*argv[optind] != '-'))
|
||||
return EOF;
|
||||
pos = 1;
|
||||
if (argv[optind][pos] == '\0')
|
||||
return EOF;
|
||||
}
|
||||
|
||||
str = strchr(optstring, argv[optind][pos]);
|
||||
if (str == NULL) {
|
||||
optopt = argv[optind][pos];
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: illegal option -- %c\n", argv[0],
|
||||
optopt);
|
||||
return '?';
|
||||
optopt = argv[optind][pos];
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: illegal option -- %c\n", argv[0],
|
||||
optopt);
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (str[1] == ':') {
|
||||
if (argv[optind][pos+1] != '\0') {
|
||||
optarg = &argv[optind][pos+1];
|
||||
return *str;
|
||||
}
|
||||
optind++;
|
||||
if (optind >= argc) {
|
||||
optopt = *str;
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], optopt);
|
||||
return '?';
|
||||
}
|
||||
optarg = argv[optind];
|
||||
optind++; pos = 0;
|
||||
return *str;
|
||||
if (argv[optind][pos+1] != '\0') {
|
||||
optarg = &argv[optind][pos+1];
|
||||
return *str;
|
||||
}
|
||||
optind++;
|
||||
if (optind >= argc) {
|
||||
optopt = *str;
|
||||
if (opterr)
|
||||
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], optopt);
|
||||
return '?';
|
||||
}
|
||||
optarg = argv[optind];
|
||||
optind++; pos = 0;
|
||||
return *str;
|
||||
}
|
||||
else {
|
||||
pos++;
|
||||
if (argv[optind][pos] == '\0') {
|
||||
optind++;
|
||||
pos = 0;
|
||||
}
|
||||
return *str;
|
||||
pos++;
|
||||
if (argv[optind][pos] == '\0') {
|
||||
optind++;
|
||||
pos = 0;
|
||||
}
|
||||
return *str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,200 +48,200 @@ static const poly_t pzero = PZERO;
|
||||
/* Definitions */
|
||||
|
||||
void mcpy(model_t *dest, const model_t *src) {
|
||||
/* Copies the parameters of src to dest.
|
||||
* dest must be an initialised model.
|
||||
*/
|
||||
if (!dest || !src) return;
|
||||
pcpy(&dest->spoly, src->spoly);
|
||||
pcpy(&dest->init, src->init);
|
||||
pcpy(&dest->xorout, src->xorout);
|
||||
pcpy(&dest->check, src->check);
|
||||
pcpy(&dest->magic, src->magic);
|
||||
dest->flags = src->flags;
|
||||
/* link to the name as it is static */
|
||||
dest->name = src->name;
|
||||
/* Copies the parameters of src to dest.
|
||||
* dest must be an initialised model.
|
||||
*/
|
||||
if (!dest || !src) return;
|
||||
pcpy(&dest->spoly, src->spoly);
|
||||
pcpy(&dest->init, src->init);
|
||||
pcpy(&dest->xorout, src->xorout);
|
||||
pcpy(&dest->check, src->check);
|
||||
pcpy(&dest->magic, src->magic);
|
||||
dest->flags = src->flags;
|
||||
/* link to the name as it is static */
|
||||
dest->name = src->name;
|
||||
}
|
||||
|
||||
void mfree(model_t *model) {
|
||||
/* Frees the parameters of model. */
|
||||
if (!model) return;
|
||||
pfree(&model->spoly);
|
||||
pfree(&model->init);
|
||||
pfree(&model->xorout);
|
||||
pfree(&model->check);
|
||||
pfree(&model->magic);
|
||||
/* not name as it is static */
|
||||
/* not model either, it might point to an array! */
|
||||
/* Frees the parameters of model. */
|
||||
if (!model) return;
|
||||
pfree(&model->spoly);
|
||||
pfree(&model->init);
|
||||
pfree(&model->xorout);
|
||||
pfree(&model->check);
|
||||
pfree(&model->magic);
|
||||
/* not name as it is static */
|
||||
/* not model either, it might point to an array! */
|
||||
}
|
||||
|
||||
int mcmp(const model_t *a, const model_t *b) {
|
||||
/* Compares a and b for identical effect, i.e. disregarding
|
||||
* trailing zeroes in parameter polys.
|
||||
* Intended for bsearch().
|
||||
*/
|
||||
int result;
|
||||
if (!a || !b) return (!b - !a);
|
||||
if ((result = psncmp(&a->spoly, &b->spoly))) return (result);
|
||||
if ((result = psncmp(&a->init, &b->init))) return (result);
|
||||
if ((a->flags & P_REFIN) && (~b->flags & P_REFIN)) return (1);
|
||||
if ((~a->flags & P_REFIN) && (b->flags & P_REFIN)) return (-1);
|
||||
if ((a->flags & P_REFOUT) && (~b->flags & P_REFOUT)) return (1);
|
||||
if ((~a->flags & P_REFOUT) && (b->flags & P_REFOUT)) return (-1);
|
||||
return (psncmp(&a->xorout, &b->xorout));
|
||||
/* Compares a and b for identical effect, i.e. disregarding
|
||||
* trailing zeroes in parameter polys.
|
||||
* Intended for bsearch().
|
||||
*/
|
||||
int result;
|
||||
if (!a || !b) return (!b - !a);
|
||||
if ((result = psncmp(&a->spoly, &b->spoly))) return (result);
|
||||
if ((result = psncmp(&a->init, &b->init))) return (result);
|
||||
if ((a->flags & P_REFIN) && (~b->flags & P_REFIN)) return (1);
|
||||
if ((~a->flags & P_REFIN) && (b->flags & P_REFIN)) return (-1);
|
||||
if ((a->flags & P_REFOUT) && (~b->flags & P_REFOUT)) return (1);
|
||||
if ((~a->flags & P_REFOUT) && (b->flags & P_REFOUT)) return (-1);
|
||||
return (psncmp(&a->xorout, &b->xorout));
|
||||
}
|
||||
|
||||
char * mtostr(const model_t *model) {
|
||||
/* Returns a malloc()-ed string containing a Williams model
|
||||
* record representing the input model.
|
||||
* mcanon() should be called on the argument before printing.
|
||||
*/
|
||||
size_t size;
|
||||
char *polystr, *initstr, *xorotstr, *checkstr, *magicstr,
|
||||
strbuf[512], *string = NULL;
|
||||
/* Returns a malloc()-ed string containing a Williams model
|
||||
* record representing the input model.
|
||||
* mcanon() should be called on the argument before printing.
|
||||
*/
|
||||
size_t size;
|
||||
char *polystr, *initstr, *xorotstr, *checkstr, *magicstr,
|
||||
strbuf[512], *string = NULL;
|
||||
|
||||
if (!model) return(NULL);
|
||||
polystr = ptostr(model->spoly, P_RTJUST, 4);
|
||||
initstr = ptostr(model->init, P_RTJUST, 4);
|
||||
xorotstr = ptostr(model->xorout, P_RTJUST, 4);
|
||||
checkstr = ptostr(model->check, P_RTJUST, 4);
|
||||
magicstr = ptostr(model->magic, P_RTJUST, 4);
|
||||
if (!model) return(NULL);
|
||||
polystr = ptostr(model->spoly, P_RTJUST, 4);
|
||||
initstr = ptostr(model->init, P_RTJUST, 4);
|
||||
xorotstr = ptostr(model->xorout, P_RTJUST, 4);
|
||||
checkstr = ptostr(model->check, P_RTJUST, 4);
|
||||
magicstr = ptostr(model->magic, P_RTJUST, 4);
|
||||
|
||||
sprintf(strbuf, "%lu", plen(model->spoly));
|
||||
size =
|
||||
82
|
||||
+ strlen(strbuf)
|
||||
+ (polystr && *polystr ? strlen(polystr) : 6)
|
||||
+ (initstr && *initstr ? strlen(initstr) : 6)
|
||||
+ (model->flags & P_REFIN ? 4 : 5)
|
||||
+ (model->flags & P_REFOUT ? 4 : 5)
|
||||
+ (xorotstr && *xorotstr ? strlen(xorotstr) : 6)
|
||||
+ (checkstr && *checkstr ? strlen(checkstr) : 6)
|
||||
+ (magicstr && *magicstr ? strlen(magicstr) : 6)
|
||||
+ (model->name && *model->name ? 2 + strlen(model->name) : 6);
|
||||
if ((string = calloc(size, sizeof(uint8_t)))) {
|
||||
sprintf(strbuf, "\"%s\"", model->name);
|
||||
sprintf(string,
|
||||
"width=%lu "
|
||||
"poly=0x%s "
|
||||
"init=0x%s "
|
||||
"refin=%s "
|
||||
"refout=%s "
|
||||
"xorout=0x%s "
|
||||
"check=0x%s "
|
||||
"residue=0x%s "
|
||||
"name=%s",
|
||||
plen(model->spoly),
|
||||
polystr && *polystr ? polystr : "(none)",
|
||||
initstr && *initstr ? initstr : "(none)",
|
||||
(model->flags & P_REFIN) ? "true" : "false",
|
||||
(model->flags & P_REFOUT) ? "true" : "false",
|
||||
xorotstr && *xorotstr ? xorotstr : "(none)",
|
||||
checkstr && *checkstr ? checkstr : "(none)",
|
||||
magicstr && *magicstr ? magicstr : "(none)",
|
||||
(model->name && *model->name) ? strbuf : "(none)");
|
||||
}
|
||||
free(polystr);
|
||||
free(initstr);
|
||||
free(xorotstr);
|
||||
free(checkstr);
|
||||
free(magicstr);
|
||||
if(!string)
|
||||
uerror("cannot allocate memory for model description");
|
||||
return(string);
|
||||
sprintf(strbuf, "%lu", plen(model->spoly));
|
||||
size =
|
||||
82
|
||||
+ strlen(strbuf)
|
||||
+ (polystr && *polystr ? strlen(polystr) : 6)
|
||||
+ (initstr && *initstr ? strlen(initstr) : 6)
|
||||
+ (model->flags & P_REFIN ? 4 : 5)
|
||||
+ (model->flags & P_REFOUT ? 4 : 5)
|
||||
+ (xorotstr && *xorotstr ? strlen(xorotstr) : 6)
|
||||
+ (checkstr && *checkstr ? strlen(checkstr) : 6)
|
||||
+ (magicstr && *magicstr ? strlen(magicstr) : 6)
|
||||
+ (model->name && *model->name ? 2 + strlen(model->name) : 6);
|
||||
if ((string = calloc(size, sizeof(uint8_t)))) {
|
||||
sprintf(strbuf, "\"%s\"", model->name);
|
||||
sprintf(string,
|
||||
"width=%lu "
|
||||
"poly=0x%s "
|
||||
"init=0x%s "
|
||||
"refin=%s "
|
||||
"refout=%s "
|
||||
"xorout=0x%s "
|
||||
"check=0x%s "
|
||||
"residue=0x%s "
|
||||
"name=%s",
|
||||
plen(model->spoly),
|
||||
polystr && *polystr ? polystr : "(none)",
|
||||
initstr && *initstr ? initstr : "(none)",
|
||||
(model->flags & P_REFIN) ? "true" : "false",
|
||||
(model->flags & P_REFOUT) ? "true" : "false",
|
||||
xorotstr && *xorotstr ? xorotstr : "(none)",
|
||||
checkstr && *checkstr ? checkstr : "(none)",
|
||||
magicstr && *magicstr ? magicstr : "(none)",
|
||||
(model->name && *model->name) ? strbuf : "(none)");
|
||||
}
|
||||
free(polystr);
|
||||
free(initstr);
|
||||
free(xorotstr);
|
||||
free(checkstr);
|
||||
free(magicstr);
|
||||
if(!string)
|
||||
uerror("cannot allocate memory for model description");
|
||||
return(string);
|
||||
}
|
||||
|
||||
void mcanon(model_t *model) {
|
||||
/* canonicalise a model */
|
||||
unsigned long dlen;
|
||||
/* canonicalise a model */
|
||||
unsigned long dlen;
|
||||
|
||||
if (!model) return;
|
||||
if (!model) return;
|
||||
|
||||
/* extending on the right here. This preserves the functionality
|
||||
* of a presumed working model.
|
||||
*/
|
||||
psnorm(&model->spoly);
|
||||
dlen = plen(model->spoly);
|
||||
praloc(&model->init, dlen);
|
||||
praloc(&model->xorout, dlen);
|
||||
/* extending on the right here. This preserves the functionality
|
||||
* of a presumed working model.
|
||||
*/
|
||||
psnorm(&model->spoly);
|
||||
dlen = plen(model->spoly);
|
||||
praloc(&model->init, dlen);
|
||||
praloc(&model->xorout, dlen);
|
||||
|
||||
/* only calculate Check if missing. Relying on all functions
|
||||
* changing parameters to call mnovel(). This is to ensure that
|
||||
* the Check value stored in the preset table is printed when
|
||||
* the model is dumped. If something goes wrong with the
|
||||
* calculator then the discrepancy with the stored Check value
|
||||
* might be noticed. Storing the Check value with each preset
|
||||
* is highly preferred.
|
||||
*/
|
||||
if (!(plen(model->check) && plen(model->magic)))
|
||||
mcheck(model);
|
||||
/* only calculate Check if missing. Relying on all functions
|
||||
* changing parameters to call mnovel(). This is to ensure that
|
||||
* the Check value stored in the preset table is printed when
|
||||
* the model is dumped. If something goes wrong with the
|
||||
* calculator then the discrepancy with the stored Check value
|
||||
* might be noticed. Storing the Check value with each preset
|
||||
* is highly preferred.
|
||||
*/
|
||||
if (!(plen(model->check) && plen(model->magic)))
|
||||
mcheck(model);
|
||||
}
|
||||
|
||||
void mcheck(model_t *model) {
|
||||
/* calculate a check for the model */
|
||||
poly_t checkstr, check, xorout, magic;
|
||||
/* calculate a check for the model */
|
||||
poly_t checkstr, check, xorout, magic;
|
||||
|
||||
/* erase existing check and magic. Models with these
|
||||
* fields recalculated should have no name.
|
||||
*/
|
||||
mnovel(model);
|
||||
/* erase existing check and magic. Models with these
|
||||
* fields recalculated should have no name.
|
||||
*/
|
||||
mnovel(model);
|
||||
|
||||
/* generate the check string with the correct bit order */
|
||||
checkstr = strtop("313233343536373839", model->flags, 8);
|
||||
check = pcrc(checkstr, model->spoly, model->init, pzero, model->flags);
|
||||
pfree(&checkstr);
|
||||
if (model->flags & P_REFOUT)
|
||||
prev(&check);
|
||||
psum(&check, model->xorout, 0UL);
|
||||
model->check = check;
|
||||
/* generate the check string with the correct bit order */
|
||||
checkstr = strtop("313233343536373839", model->flags, 8);
|
||||
check = pcrc(checkstr, model->spoly, model->init, pzero, model->flags);
|
||||
pfree(&checkstr);
|
||||
if (model->flags & P_REFOUT)
|
||||
prev(&check);
|
||||
psum(&check, model->xorout, 0UL);
|
||||
model->check = check;
|
||||
|
||||
/* calculate residue by emulating receipt of error-free message
|
||||
* The residue of a crossed-endian model is calculated assuming
|
||||
* that the characters of the received CRC are specially
|
||||
* reflected before submitting the codeword.
|
||||
*/
|
||||
xorout=pclone(model->xorout);
|
||||
if (model->flags & P_REFOUT)
|
||||
prev(&xorout);
|
||||
magic = pcrc(xorout, model->spoly, pzero, pzero, model->flags);
|
||||
pfree(&xorout);
|
||||
if (model->flags & P_REFIN)
|
||||
prev(&magic);
|
||||
model->magic = magic;
|
||||
/* calculate residue by emulating receipt of error-free message
|
||||
* The residue of a crossed-endian model is calculated assuming
|
||||
* that the characters of the received CRC are specially
|
||||
* reflected before submitting the codeword.
|
||||
*/
|
||||
xorout=pclone(model->xorout);
|
||||
if (model->flags & P_REFOUT)
|
||||
prev(&xorout);
|
||||
magic = pcrc(xorout, model->spoly, pzero, pzero, model->flags);
|
||||
pfree(&xorout);
|
||||
if (model->flags & P_REFIN)
|
||||
prev(&magic);
|
||||
model->magic = magic;
|
||||
}
|
||||
|
||||
void mrev(model_t *model) {
|
||||
/* reverse the model to calculate reversed CRCs */
|
||||
/* Here we invert RefIn and RefOut so that the user need only
|
||||
* reverse the order of characters in the arguments, not the
|
||||
* characters themselves. If RefOut=True, the mirror image of
|
||||
* Init seen through RefOut becomes XorOut, and as RefOut
|
||||
* becomes false, the XorOut value moved to Init stays upright.
|
||||
* If RefOut=False, Init transfers to XorOut without reflection
|
||||
* but the new Init must be reflected to present the same image,
|
||||
* as RefOut becomes true.
|
||||
*/
|
||||
poly_t temp;
|
||||
/* reverse the model to calculate reversed CRCs */
|
||||
/* Here we invert RefIn and RefOut so that the user need only
|
||||
* reverse the order of characters in the arguments, not the
|
||||
* characters themselves. If RefOut=True, the mirror image of
|
||||
* Init seen through RefOut becomes XorOut, and as RefOut
|
||||
* becomes false, the XorOut value moved to Init stays upright.
|
||||
* If RefOut=False, Init transfers to XorOut without reflection
|
||||
* but the new Init must be reflected to present the same image,
|
||||
* as RefOut becomes true.
|
||||
*/
|
||||
poly_t temp;
|
||||
|
||||
prcp(&model->spoly);
|
||||
if (model->flags & P_REFOUT)
|
||||
prev(&model->init);
|
||||
else
|
||||
prev(&model->xorout);
|
||||
prcp(&model->spoly);
|
||||
if (model->flags & P_REFOUT)
|
||||
prev(&model->init);
|
||||
else
|
||||
prev(&model->xorout);
|
||||
|
||||
/* exchange init and xorout */
|
||||
temp = model->init;
|
||||
model->init = model->xorout;
|
||||
model->xorout = temp;
|
||||
/* exchange init and xorout */
|
||||
temp = model->init;
|
||||
model->init = model->xorout;
|
||||
model->xorout = temp;
|
||||
|
||||
/* invert refin and refout */
|
||||
model->flags ^= P_REFIN | P_REFOUT;
|
||||
/* invert refin and refout */
|
||||
model->flags ^= P_REFIN | P_REFOUT;
|
||||
|
||||
mnovel(model);
|
||||
mnovel(model);
|
||||
}
|
||||
|
||||
void mnovel(model_t *model) {
|
||||
/* remove name and check string from modified model */
|
||||
model->name = NULL;
|
||||
pfree(&model->check);
|
||||
pfree(&model->magic);
|
||||
/* remove name and check string from modified model */
|
||||
model->name = NULL;
|
||||
pfree(&model->check);
|
||||
pfree(&model->magic);
|
||||
}
|
||||
|
||||
1746
client/reveng/poly.c
1746
client/reveng/poly.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -32,9 +32,9 @@
|
||||
* 2011-01-17: fixed ANSI C warnings
|
||||
* 2011-01-08: fixed calini(), modini() caters for crossed-endian algos
|
||||
* 2011-01-04: renamed functions, added calini(), factored pshres();
|
||||
* rewrote engini() and implemented quick Init search
|
||||
* rewrote engini() and implemented quick Init search
|
||||
* 2011-01-01: reveng() initialises terminating entry, addparms()
|
||||
* initialises all fields
|
||||
* initialises all fields
|
||||
* 2010-12-26: renamed CRC RevEng. right results, rejects polys faster
|
||||
* 2010-12-24: completed, first tests (unsuccessful)
|
||||
* 2010-12-21: completed modulate(), partial sketch of reveng()
|
||||
@@ -63,438 +63,438 @@ static const poly_t pzero = PZERO;
|
||||
|
||||
model_t *
|
||||
reveng(const model_t *guess, const poly_t qpoly, int rflags, int args, const poly_t *argpolys) {
|
||||
/* Complete the parameters of a model by calculation or brute search. */
|
||||
poly_t *pworks, *wptr, rem, gpoly;
|
||||
model_t *result = NULL, *rptr;
|
||||
int resc = 0;
|
||||
unsigned long spin = 0, seq = 0;
|
||||
/* Complete the parameters of a model by calculation or brute search. */
|
||||
poly_t *pworks, *wptr, rem, gpoly;
|
||||
model_t *result = NULL, *rptr;
|
||||
int resc = 0;
|
||||
unsigned long spin = 0, seq = 0;
|
||||
|
||||
if(~rflags & R_HAVEP) {
|
||||
/* The poly is not known.
|
||||
* Produce a list of differences between the arguments.
|
||||
*/
|
||||
pworks = modpol(guess->init, rflags, args, argpolys);
|
||||
if(!pworks || !plen(*pworks)) {
|
||||
free(pworks);
|
||||
goto requit;
|
||||
}
|
||||
/* Initialise the guessed poly to the starting value. */
|
||||
gpoly = pclone(guess->spoly);
|
||||
/* Clear the least significant term, to be set in the
|
||||
* loop. qpoly does not need fixing as it is only
|
||||
* compared with odd polys.
|
||||
*/
|
||||
if(plen(gpoly))
|
||||
pshift(&gpoly, gpoly, 0UL, 0UL, plen(gpoly) - 1UL, 1UL);
|
||||
if(~rflags & R_HAVEP) {
|
||||
/* The poly is not known.
|
||||
* Produce a list of differences between the arguments.
|
||||
*/
|
||||
pworks = modpol(guess->init, rflags, args, argpolys);
|
||||
if(!pworks || !plen(*pworks)) {
|
||||
free(pworks);
|
||||
goto requit;
|
||||
}
|
||||
/* Initialise the guessed poly to the starting value. */
|
||||
gpoly = pclone(guess->spoly);
|
||||
/* Clear the least significant term, to be set in the
|
||||
* loop. qpoly does not need fixing as it is only
|
||||
* compared with odd polys.
|
||||
*/
|
||||
if(plen(gpoly))
|
||||
pshift(&gpoly, gpoly, 0UL, 0UL, plen(gpoly) - 1UL, 1UL);
|
||||
|
||||
while(piter(&gpoly) && (~rflags & R_HAVEQ || pcmp(&gpoly, &qpoly) < 0)) {
|
||||
/* For each possible poly of this size, try
|
||||
* dividing all the differences in the list.
|
||||
*/
|
||||
if(!(spin++ & R_SPMASK)) {
|
||||
uprog(gpoly, guess->flags, seq++);
|
||||
}
|
||||
for(wptr = pworks; plen(*wptr); ++wptr) {
|
||||
/* straight divide message by poly, don't multiply by x^n */
|
||||
rem = pcrc(*wptr, gpoly, pzero, pzero, 0);
|
||||
if(ptst(rem)) {
|
||||
pfree(&rem);
|
||||
break;
|
||||
} else
|
||||
pfree(&rem);
|
||||
}
|
||||
/* If gpoly divides all the differences, it is a
|
||||
* candidate. Search for an Init value for this
|
||||
* poly or if Init is known, log the result.
|
||||
*/
|
||||
if(!plen(*wptr)) {
|
||||
/* gpoly is a candidate poly */
|
||||
if(rflags & R_HAVEI && rflags & R_HAVEX)
|
||||
chkres(&resc, &result, gpoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
||||
else if(rflags & R_HAVEI)
|
||||
calout(&resc, &result, gpoly, guess->init, guess->flags, args, argpolys);
|
||||
else if(rflags & R_HAVEX)
|
||||
calini(&resc, &result, gpoly, guess->flags, guess->xorout, args, argpolys);
|
||||
else
|
||||
engini(&resc, &result, gpoly, guess->flags, args, argpolys);
|
||||
}
|
||||
if(!piter(&gpoly))
|
||||
break;
|
||||
}
|
||||
/* Finished with gpoly and the differences list, free them.
|
||||
*/
|
||||
pfree(&gpoly);
|
||||
for(wptr = pworks; plen(*wptr); ++wptr)
|
||||
pfree(wptr);
|
||||
free(pworks);
|
||||
}
|
||||
else if(rflags & R_HAVEI && rflags & R_HAVEX)
|
||||
/* All parameters are known! Submit the result if we get here */
|
||||
chkres(&resc, &result, guess->spoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
||||
else if(rflags & R_HAVEI)
|
||||
/* Poly and Init are known, calculate XorOut */
|
||||
calout(&resc, &result, guess->spoly, guess->init, guess->flags, args, argpolys);
|
||||
else if(rflags & R_HAVEX)
|
||||
/* Poly and XorOut are known, calculate Init */
|
||||
calini(&resc, &result, guess->spoly, guess->flags, guess->xorout, args, argpolys);
|
||||
else
|
||||
/* Poly is known but not Init; search for Init. */
|
||||
engini(&resc, &result, guess->spoly, guess->flags, args, argpolys);
|
||||
while(piter(&gpoly) && (~rflags & R_HAVEQ || pcmp(&gpoly, &qpoly) < 0)) {
|
||||
/* For each possible poly of this size, try
|
||||
* dividing all the differences in the list.
|
||||
*/
|
||||
if(!(spin++ & R_SPMASK)) {
|
||||
uprog(gpoly, guess->flags, seq++);
|
||||
}
|
||||
for(wptr = pworks; plen(*wptr); ++wptr) {
|
||||
/* straight divide message by poly, don't multiply by x^n */
|
||||
rem = pcrc(*wptr, gpoly, pzero, pzero, 0);
|
||||
if(ptst(rem)) {
|
||||
pfree(&rem);
|
||||
break;
|
||||
} else
|
||||
pfree(&rem);
|
||||
}
|
||||
/* If gpoly divides all the differences, it is a
|
||||
* candidate. Search for an Init value for this
|
||||
* poly or if Init is known, log the result.
|
||||
*/
|
||||
if(!plen(*wptr)) {
|
||||
/* gpoly is a candidate poly */
|
||||
if(rflags & R_HAVEI && rflags & R_HAVEX)
|
||||
chkres(&resc, &result, gpoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
||||
else if(rflags & R_HAVEI)
|
||||
calout(&resc, &result, gpoly, guess->init, guess->flags, args, argpolys);
|
||||
else if(rflags & R_HAVEX)
|
||||
calini(&resc, &result, gpoly, guess->flags, guess->xorout, args, argpolys);
|
||||
else
|
||||
engini(&resc, &result, gpoly, guess->flags, args, argpolys);
|
||||
}
|
||||
if(!piter(&gpoly))
|
||||
break;
|
||||
}
|
||||
/* Finished with gpoly and the differences list, free them.
|
||||
*/
|
||||
pfree(&gpoly);
|
||||
for(wptr = pworks; plen(*wptr); ++wptr)
|
||||
pfree(wptr);
|
||||
free(pworks);
|
||||
}
|
||||
else if(rflags & R_HAVEI && rflags & R_HAVEX)
|
||||
/* All parameters are known! Submit the result if we get here */
|
||||
chkres(&resc, &result, guess->spoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
||||
else if(rflags & R_HAVEI)
|
||||
/* Poly and Init are known, calculate XorOut */
|
||||
calout(&resc, &result, guess->spoly, guess->init, guess->flags, args, argpolys);
|
||||
else if(rflags & R_HAVEX)
|
||||
/* Poly and XorOut are known, calculate Init */
|
||||
calini(&resc, &result, guess->spoly, guess->flags, guess->xorout, args, argpolys);
|
||||
else
|
||||
/* Poly is known but not Init; search for Init. */
|
||||
engini(&resc, &result, guess->spoly, guess->flags, args, argpolys);
|
||||
|
||||
requit:
|
||||
if(!(result = realloc(result, ++resc * sizeof(model_t)))) {
|
||||
uerror("cannot reallocate result array");
|
||||
return NULL;
|
||||
}
|
||||
rptr = result + resc - 1;
|
||||
rptr->spoly = pzero;
|
||||
rptr->init = pzero;
|
||||
rptr->flags = 0;
|
||||
rptr->xorout = pzero;
|
||||
rptr->check = pzero;
|
||||
rptr->magic = pzero;
|
||||
rptr->name = NULL;
|
||||
if(!(result = realloc(result, ++resc * sizeof(model_t)))) {
|
||||
uerror("cannot reallocate result array");
|
||||
return NULL;
|
||||
}
|
||||
rptr = result + resc - 1;
|
||||
rptr->spoly = pzero;
|
||||
rptr->init = pzero;
|
||||
rptr->flags = 0;
|
||||
rptr->xorout = pzero;
|
||||
rptr->check = pzero;
|
||||
rptr->magic = pzero;
|
||||
rptr->name = NULL;
|
||||
|
||||
return(result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static poly_t *
|
||||
modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) {
|
||||
/* Produce, in ascending length order, a list of differences
|
||||
* between the arguments in the list by summing pairs of arguments.
|
||||
* If R_HAVEI is not set in rflags, only pairs of equal length are
|
||||
* summed.
|
||||
* Otherwise, sums of right-aligned pairs are also returned, with
|
||||
* the supplied init poly added to the leftmost terms of each
|
||||
* poly of the pair.
|
||||
*/
|
||||
poly_t work, swap, *result, *rptr, *iptr;
|
||||
const poly_t *aptr, *bptr, *eptr = argpolys + args;
|
||||
unsigned long alen, blen;
|
||||
/* Produce, in ascending length order, a list of differences
|
||||
* between the arguments in the list by summing pairs of arguments.
|
||||
* If R_HAVEI is not set in rflags, only pairs of equal length are
|
||||
* summed.
|
||||
* Otherwise, sums of right-aligned pairs are also returned, with
|
||||
* the supplied init poly added to the leftmost terms of each
|
||||
* poly of the pair.
|
||||
*/
|
||||
poly_t work, swap, *result, *rptr, *iptr;
|
||||
const poly_t *aptr, *bptr, *eptr = argpolys + args;
|
||||
unsigned long alen, blen;
|
||||
|
||||
if(args < 2) return(NULL);
|
||||
if(args < 2) return(NULL);
|
||||
|
||||
result = calloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t), sizeof(char));
|
||||
if(!result)
|
||||
uerror("cannot allocate memory for codeword table");
|
||||
result = calloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t), sizeof(char));
|
||||
if(!result)
|
||||
uerror("cannot allocate memory for codeword table");
|
||||
|
||||
rptr = result;
|
||||
rptr = result;
|
||||
|
||||
for(aptr = argpolys; aptr < eptr; ++aptr) {
|
||||
alen = plen(*aptr);
|
||||
for(bptr = aptr + 1; bptr < eptr; ++bptr) {
|
||||
blen = plen(*bptr);
|
||||
if(alen == blen) {
|
||||
work = pclone(*aptr);
|
||||
psum(&work, *bptr, 0UL);
|
||||
} else if(rflags & R_HAVEI && alen < blen) {
|
||||
work = pclone(*bptr);
|
||||
psum(&work, *aptr, blen - alen);
|
||||
psum(&work, init, 0UL);
|
||||
psum(&work, init, blen - alen);
|
||||
} else if(rflags & R_HAVEI /* && alen > blen */) {
|
||||
work = pclone(*aptr);
|
||||
psum(&work, *bptr, alen - blen);
|
||||
psum(&work, init, 0UL);
|
||||
psum(&work, init, alen - blen);
|
||||
} else
|
||||
work = pzero;
|
||||
for(aptr = argpolys; aptr < eptr; ++aptr) {
|
||||
alen = plen(*aptr);
|
||||
for(bptr = aptr + 1; bptr < eptr; ++bptr) {
|
||||
blen = plen(*bptr);
|
||||
if(alen == blen) {
|
||||
work = pclone(*aptr);
|
||||
psum(&work, *bptr, 0UL);
|
||||
} else if(rflags & R_HAVEI && alen < blen) {
|
||||
work = pclone(*bptr);
|
||||
psum(&work, *aptr, blen - alen);
|
||||
psum(&work, init, 0UL);
|
||||
psum(&work, init, blen - alen);
|
||||
} else if(rflags & R_HAVEI /* && alen > blen */) {
|
||||
work = pclone(*aptr);
|
||||
psum(&work, *bptr, alen - blen);
|
||||
psum(&work, init, 0UL);
|
||||
psum(&work, init, alen - blen);
|
||||
} else
|
||||
work = pzero;
|
||||
|
||||
if(plen(work))
|
||||
pnorm(&work);
|
||||
if((blen = plen(work))) {
|
||||
/* insert work into result[] in ascending order of length */
|
||||
for(iptr = result; iptr < rptr; ++iptr) {
|
||||
if(plen(work) < plen(*iptr)) {
|
||||
swap = *iptr;
|
||||
*iptr = work;
|
||||
work = swap;
|
||||
}
|
||||
else if(plen(*iptr) == blen && !pcmp(&work, iptr)) {
|
||||
pfree(&work);
|
||||
work = *--rptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*rptr++ = work;
|
||||
}
|
||||
}
|
||||
}
|
||||
*rptr = pzero;
|
||||
return(result);
|
||||
if(plen(work))
|
||||
pnorm(&work);
|
||||
if((blen = plen(work))) {
|
||||
/* insert work into result[] in ascending order of length */
|
||||
for(iptr = result; iptr < rptr; ++iptr) {
|
||||
if(plen(work) < plen(*iptr)) {
|
||||
swap = *iptr;
|
||||
*iptr = work;
|
||||
work = swap;
|
||||
}
|
||||
else if(plen(*iptr) == blen && !pcmp(&work, iptr)) {
|
||||
pfree(&work);
|
||||
work = *--rptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*rptr++ = work;
|
||||
}
|
||||
}
|
||||
}
|
||||
*rptr = pzero;
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, const poly_t *argpolys) {
|
||||
/* Search for init values implied by the arguments.
|
||||
* Method from: Ewing, Gregory C. (March 2010).
|
||||
* "Reverse-Engineering a CRC Algorithm". Christchurch:
|
||||
* University of Canterbury.
|
||||
* <http://www.cosc.canterbury.ac.nz/greg.ewing/essays/
|
||||
* CRC-Reverse-Engineering.html>
|
||||
*/
|
||||
poly_t apoly = PZERO, bpoly, pone = PZERO, *mat, *jptr;
|
||||
const poly_t *aptr, *bptr, *iptr;
|
||||
unsigned long alen, blen, dlen, ilen, i, j;
|
||||
int cy;
|
||||
/* Search for init values implied by the arguments.
|
||||
* Method from: Ewing, Gregory C. (March 2010).
|
||||
* "Reverse-Engineering a CRC Algorithm". Christchurch:
|
||||
* University of Canterbury.
|
||||
* <http://www.cosc.canterbury.ac.nz/greg.ewing/essays/
|
||||
* CRC-Reverse-Engineering.html>
|
||||
*/
|
||||
poly_t apoly = PZERO, bpoly, pone = PZERO, *mat, *jptr;
|
||||
const poly_t *aptr, *bptr, *iptr;
|
||||
unsigned long alen, blen, dlen, ilen, i, j;
|
||||
int cy;
|
||||
|
||||
dlen = plen(divisor);
|
||||
dlen = plen(divisor);
|
||||
|
||||
/* Allocate the CRC matrix */
|
||||
mat = (poly_t *) calloc((dlen << 1) * sizeof(poly_t), sizeof(char));
|
||||
if(!mat)
|
||||
uerror("cannot allocate memory for CRC matrix");
|
||||
/* Allocate the CRC matrix */
|
||||
mat = (poly_t *) calloc((dlen << 1) * sizeof(poly_t), sizeof(char));
|
||||
if(!mat)
|
||||
uerror("cannot allocate memory for CRC matrix");
|
||||
|
||||
/* Find arguments of the two shortest lengths */
|
||||
alen = blen = plen(*(aptr = bptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
bptr = aptr; blen = alen;
|
||||
aptr = iptr; alen = ilen;
|
||||
} else if(ilen > alen && (aptr == bptr || ilen < blen)) {
|
||||
bptr = iptr; blen = ilen;
|
||||
}
|
||||
}
|
||||
if(aptr == bptr) {
|
||||
/* if no arguments are suitable, calculate Init with an
|
||||
* assumed XorOut of 0. Create a padded XorOut
|
||||
*/
|
||||
palloc(&apoly, dlen);
|
||||
calini(resc, result, divisor, flags, apoly, args, argpolys);
|
||||
pfree(&apoly);
|
||||
free(mat);
|
||||
return;
|
||||
}
|
||||
/* Find arguments of the two shortest lengths */
|
||||
alen = blen = plen(*(aptr = bptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
bptr = aptr; blen = alen;
|
||||
aptr = iptr; alen = ilen;
|
||||
} else if(ilen > alen && (aptr == bptr || ilen < blen)) {
|
||||
bptr = iptr; blen = ilen;
|
||||
}
|
||||
}
|
||||
if(aptr == bptr) {
|
||||
/* if no arguments are suitable, calculate Init with an
|
||||
* assumed XorOut of 0. Create a padded XorOut
|
||||
*/
|
||||
palloc(&apoly, dlen);
|
||||
calini(resc, result, divisor, flags, apoly, args, argpolys);
|
||||
pfree(&apoly);
|
||||
free(mat);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the potential contribution of the bottom bit of Init */
|
||||
palloc(&pone, 1UL);
|
||||
piter(&pone);
|
||||
if(blen < (dlen << 1)) {
|
||||
palloc(&apoly, dlen); /* >= 1 */
|
||||
psum(&apoly, pone, (dlen << 1) - 1UL - blen); /* >= 0 */
|
||||
psum(&apoly, pone, (dlen << 1) - 1UL - alen); /* >= 1 */
|
||||
} else {
|
||||
palloc(&apoly, blen - dlen + 1UL); /* > dlen */
|
||||
psum(&apoly, pone, 0UL);
|
||||
psum(&apoly, pone, blen - alen); /* >= 1 */
|
||||
}
|
||||
if(plen(apoly) > dlen) {
|
||||
mat[dlen] = pcrc(apoly, divisor, pzero, pzero, 0);
|
||||
pfree(&apoly);
|
||||
} else {
|
||||
mat[dlen] = apoly;
|
||||
}
|
||||
/* Find the potential contribution of the bottom bit of Init */
|
||||
palloc(&pone, 1UL);
|
||||
piter(&pone);
|
||||
if(blen < (dlen << 1)) {
|
||||
palloc(&apoly, dlen); /* >= 1 */
|
||||
psum(&apoly, pone, (dlen << 1) - 1UL - blen); /* >= 0 */
|
||||
psum(&apoly, pone, (dlen << 1) - 1UL - alen); /* >= 1 */
|
||||
} else {
|
||||
palloc(&apoly, blen - dlen + 1UL); /* > dlen */
|
||||
psum(&apoly, pone, 0UL);
|
||||
psum(&apoly, pone, blen - alen); /* >= 1 */
|
||||
}
|
||||
if(plen(apoly) > dlen) {
|
||||
mat[dlen] = pcrc(apoly, divisor, pzero, pzero, 0);
|
||||
pfree(&apoly);
|
||||
} else {
|
||||
mat[dlen] = apoly;
|
||||
}
|
||||
|
||||
/* Find the actual contribution of Init */
|
||||
apoly = pcrc(*aptr, divisor, pzero, pzero, 0);
|
||||
bpoly = pcrc(*bptr, divisor, pzero, apoly, 0);
|
||||
/* Find the actual contribution of Init */
|
||||
apoly = pcrc(*aptr, divisor, pzero, pzero, 0);
|
||||
bpoly = pcrc(*bptr, divisor, pzero, apoly, 0);
|
||||
|
||||
/* Populate the matrix */
|
||||
palloc(&apoly, 1UL);
|
||||
for(jptr=mat; jptr<mat+dlen; ++jptr)
|
||||
*jptr = pzero;
|
||||
for(iptr = jptr++; jptr < mat + (dlen << 1); iptr = jptr++)
|
||||
*jptr = pcrc(apoly, divisor, *iptr, pzero, P_MULXN);
|
||||
pfree(&apoly);
|
||||
/* Populate the matrix */
|
||||
palloc(&apoly, 1UL);
|
||||
for(jptr=mat; jptr<mat+dlen; ++jptr)
|
||||
*jptr = pzero;
|
||||
for(iptr = jptr++; jptr < mat + (dlen << 1); iptr = jptr++)
|
||||
*jptr = pcrc(apoly, divisor, *iptr, pzero, P_MULXN);
|
||||
pfree(&apoly);
|
||||
|
||||
/* Transpose the matrix, augment with the Init contribution
|
||||
* and convert to row echelon form
|
||||
*/
|
||||
for(i=0UL; i<dlen; ++i) {
|
||||
apoly = pzero;
|
||||
iptr = mat + (dlen << 1);
|
||||
for(j=0UL; j<dlen; ++j)
|
||||
ppaste(&apoly, *--iptr, i, j, j + 1UL, dlen + 1UL);
|
||||
if(ptst(apoly))
|
||||
ppaste(&apoly, bpoly, i, dlen, dlen + 1UL, dlen + 1UL);
|
||||
j = pfirst(apoly);
|
||||
while(j < dlen && !pident(mat[j], pzero)) {
|
||||
psum(&apoly, mat[j], 0UL); /* pfirst(apoly) > j */
|
||||
j = pfirst(apoly);
|
||||
}
|
||||
if(j < dlen)
|
||||
mat[j] = apoly; /* pident(mat[j], pzero) || pfirst(mat[j]) == j */
|
||||
else
|
||||
pfree(&apoly);
|
||||
}
|
||||
palloc(&bpoly, dlen + 1UL);
|
||||
psum(&bpoly, pone, dlen);
|
||||
/* Transpose the matrix, augment with the Init contribution
|
||||
* and convert to row echelon form
|
||||
*/
|
||||
for(i=0UL; i<dlen; ++i) {
|
||||
apoly = pzero;
|
||||
iptr = mat + (dlen << 1);
|
||||
for(j=0UL; j<dlen; ++j)
|
||||
ppaste(&apoly, *--iptr, i, j, j + 1UL, dlen + 1UL);
|
||||
if(ptst(apoly))
|
||||
ppaste(&apoly, bpoly, i, dlen, dlen + 1UL, dlen + 1UL);
|
||||
j = pfirst(apoly);
|
||||
while(j < dlen && !pident(mat[j], pzero)) {
|
||||
psum(&apoly, mat[j], 0UL); /* pfirst(apoly) > j */
|
||||
j = pfirst(apoly);
|
||||
}
|
||||
if(j < dlen)
|
||||
mat[j] = apoly; /* pident(mat[j], pzero) || pfirst(mat[j]) == j */
|
||||
else
|
||||
pfree(&apoly);
|
||||
}
|
||||
palloc(&bpoly, dlen + 1UL);
|
||||
psum(&bpoly, pone, dlen);
|
||||
|
||||
/* Iterate through all solutions */
|
||||
do {
|
||||
/* Solve the matrix by Gaussian elimination.
|
||||
* The parity of the result, masked by each row, should be even.
|
||||
*/
|
||||
cy = 1;
|
||||
apoly = pclone(bpoly);
|
||||
jptr = mat + dlen;
|
||||
for(i=0UL; i<dlen; ++i) {
|
||||
/* Compute next bit of Init */
|
||||
if(pmpar(apoly, *--jptr))
|
||||
psum(&apoly, pone, dlen - 1UL - i);
|
||||
/* Toggle each zero row with carry, for next iteration */
|
||||
if(cy) {
|
||||
if(pident(*jptr, pzero)) {
|
||||
/* 0 to 1, no carry */
|
||||
*jptr = bpoly;
|
||||
cy = 0;
|
||||
} else if(pident(*jptr, bpoly)) {
|
||||
/* 1 to 0, carry forward */
|
||||
*jptr = pzero;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Iterate through all solutions */
|
||||
do {
|
||||
/* Solve the matrix by Gaussian elimination.
|
||||
* The parity of the result, masked by each row, should be even.
|
||||
*/
|
||||
cy = 1;
|
||||
apoly = pclone(bpoly);
|
||||
jptr = mat + dlen;
|
||||
for(i=0UL; i<dlen; ++i) {
|
||||
/* Compute next bit of Init */
|
||||
if(pmpar(apoly, *--jptr))
|
||||
psum(&apoly, pone, dlen - 1UL - i);
|
||||
/* Toggle each zero row with carry, for next iteration */
|
||||
if(cy) {
|
||||
if(pident(*jptr, pzero)) {
|
||||
/* 0 to 1, no carry */
|
||||
*jptr = bpoly;
|
||||
cy = 0;
|
||||
} else if(pident(*jptr, bpoly)) {
|
||||
/* 1 to 0, carry forward */
|
||||
*jptr = pzero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Trim the augment mask bit */
|
||||
praloc(&apoly, dlen);
|
||||
/* Trim the augment mask bit */
|
||||
praloc(&apoly, dlen);
|
||||
|
||||
/* Test the Init value and add to results if correct */
|
||||
calout(resc, result, divisor, apoly, flags, args, argpolys);
|
||||
pfree(&apoly);
|
||||
} while(!cy);
|
||||
pfree(&pone);
|
||||
pfree(&bpoly);
|
||||
/* Test the Init value and add to results if correct */
|
||||
calout(resc, result, divisor, apoly, flags, args, argpolys);
|
||||
pfree(&apoly);
|
||||
} while(!cy);
|
||||
pfree(&pone);
|
||||
pfree(&bpoly);
|
||||
|
||||
/* Free the matrix. */
|
||||
for(jptr=mat; jptr < mat + (dlen << 1); ++jptr)
|
||||
pfree(jptr);
|
||||
free(mat);
|
||||
/* Free the matrix. */
|
||||
for(jptr=mat; jptr < mat + (dlen << 1); ++jptr)
|
||||
pfree(jptr);
|
||||
free(mat);
|
||||
}
|
||||
|
||||
static void
|
||||
calout(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, int args, const poly_t *argpolys) {
|
||||
/* Calculate Xorout, check it against all the arguments and
|
||||
* add to results if consistent.
|
||||
*/
|
||||
poly_t xorout;
|
||||
const poly_t *aptr, *iptr;
|
||||
unsigned long alen, ilen;
|
||||
/* Calculate Xorout, check it against all the arguments and
|
||||
* add to results if consistent.
|
||||
*/
|
||||
poly_t xorout;
|
||||
const poly_t *aptr, *iptr;
|
||||
unsigned long alen, ilen;
|
||||
|
||||
if(args < 1) return;
|
||||
if(args < 1) return;
|
||||
|
||||
/* find argument of the shortest length */
|
||||
alen = plen(*(aptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
aptr = iptr; alen = ilen;
|
||||
}
|
||||
}
|
||||
/* find argument of the shortest length */
|
||||
alen = plen(*(aptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
aptr = iptr; alen = ilen;
|
||||
}
|
||||
}
|
||||
|
||||
xorout = pcrc(*aptr, divisor, init, pzero, 0);
|
||||
/* On little-endian algorithms, the calculations yield
|
||||
* the reverse of the actual xorout: in the Williams
|
||||
* model, the refout stage intervenes between init and
|
||||
* xorout.
|
||||
*/
|
||||
if(flags & P_REFOUT)
|
||||
prev(&xorout);
|
||||
xorout = pcrc(*aptr, divisor, init, pzero, 0);
|
||||
/* On little-endian algorithms, the calculations yield
|
||||
* the reverse of the actual xorout: in the Williams
|
||||
* model, the refout stage intervenes between init and
|
||||
* xorout.
|
||||
*/
|
||||
if(flags & P_REFOUT)
|
||||
prev(&xorout);
|
||||
|
||||
/* Submit the model to the results table.
|
||||
* Could skip the shortest argument but we wish to check our
|
||||
* calculation.
|
||||
*/
|
||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
||||
pfree(&xorout);
|
||||
/* Submit the model to the results table.
|
||||
* Could skip the shortest argument but we wish to check our
|
||||
* calculation.
|
||||
*/
|
||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
||||
pfree(&xorout);
|
||||
}
|
||||
|
||||
static void
|
||||
calini(int *resc, model_t **result, const poly_t divisor, int flags, const poly_t xorout, int args, const poly_t *argpolys) {
|
||||
/* Calculate Init, check it against all the arguments and add to
|
||||
* results if consistent.
|
||||
*/
|
||||
poly_t rcpdiv, rxor, arg, init;
|
||||
const poly_t *aptr, *iptr;
|
||||
unsigned long alen, ilen;
|
||||
/* Calculate Init, check it against all the arguments and add to
|
||||
* results if consistent.
|
||||
*/
|
||||
poly_t rcpdiv, rxor, arg, init;
|
||||
const poly_t *aptr, *iptr;
|
||||
unsigned long alen, ilen;
|
||||
|
||||
if(args < 1) return;
|
||||
if(args < 1) return;
|
||||
|
||||
/* find argument of the shortest length */
|
||||
alen = plen(*(aptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
aptr = iptr; alen = ilen;
|
||||
}
|
||||
}
|
||||
/* find argument of the shortest length */
|
||||
alen = plen(*(aptr = iptr = argpolys));
|
||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
||||
ilen = plen(*iptr);
|
||||
if(ilen < alen) {
|
||||
aptr = iptr; alen = ilen;
|
||||
}
|
||||
}
|
||||
|
||||
rcpdiv = pclone(divisor);
|
||||
prcp(&rcpdiv);
|
||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
||||
* stage. To reverse the CRC calculation we need rxor to be the
|
||||
* mirror image of the forward XorOut.
|
||||
*/
|
||||
rxor = pclone(xorout);
|
||||
if(~flags & P_REFOUT)
|
||||
prev(&rxor);
|
||||
arg = pclone(*aptr);
|
||||
prev(&arg);
|
||||
rcpdiv = pclone(divisor);
|
||||
prcp(&rcpdiv);
|
||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
||||
* stage. To reverse the CRC calculation we need rxor to be the
|
||||
* mirror image of the forward XorOut.
|
||||
*/
|
||||
rxor = pclone(xorout);
|
||||
if(~flags & P_REFOUT)
|
||||
prev(&rxor);
|
||||
arg = pclone(*aptr);
|
||||
prev(&arg);
|
||||
|
||||
init = pcrc(arg, rcpdiv, rxor, pzero, 0);
|
||||
pfree(&arg);
|
||||
pfree(&rxor);
|
||||
pfree(&rcpdiv);
|
||||
prev(&init);
|
||||
init = pcrc(arg, rcpdiv, rxor, pzero, 0);
|
||||
pfree(&arg);
|
||||
pfree(&rxor);
|
||||
pfree(&rcpdiv);
|
||||
prev(&init);
|
||||
|
||||
/* Submit the model to the results table.
|
||||
* Could skip the shortest argument but we wish to check our
|
||||
* calculation.
|
||||
*/
|
||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
||||
pfree(&init);
|
||||
/* Submit the model to the results table.
|
||||
* Could skip the shortest argument but we wish to check our
|
||||
* calculation.
|
||||
*/
|
||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
||||
pfree(&init);
|
||||
}
|
||||
|
||||
static void
|
||||
chkres(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, const poly_t xorout, int args, const poly_t *argpolys) {
|
||||
/* Checks a model against the argument list, and adds to the
|
||||
* external results table if consistent.
|
||||
* Extends the result array and updates the external pointer if
|
||||
* necessary.
|
||||
*/
|
||||
model_t *rptr;
|
||||
poly_t xor, crc;
|
||||
const poly_t *aptr = argpolys, *const eptr = argpolys + args;
|
||||
/* Checks a model against the argument list, and adds to the
|
||||
* external results table if consistent.
|
||||
* Extends the result array and updates the external pointer if
|
||||
* necessary.
|
||||
*/
|
||||
model_t *rptr;
|
||||
poly_t xor, crc;
|
||||
const poly_t *aptr = argpolys, *const eptr = argpolys + args;
|
||||
|
||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
||||
* stage.
|
||||
*/
|
||||
xor = pclone(xorout);
|
||||
if(flags & P_REFOUT)
|
||||
prev(&xor);
|
||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
||||
* stage.
|
||||
*/
|
||||
xor = pclone(xorout);
|
||||
if(flags & P_REFOUT)
|
||||
prev(&xor);
|
||||
|
||||
for(; aptr < eptr; ++aptr) {
|
||||
crc = pcrc(*aptr, divisor, init, xor, 0);
|
||||
if(ptst(crc)) {
|
||||
pfree(&crc);
|
||||
break;
|
||||
} else {
|
||||
pfree(&crc);
|
||||
}
|
||||
}
|
||||
pfree(&xor);
|
||||
if(aptr != eptr) return;
|
||||
for(; aptr < eptr; ++aptr) {
|
||||
crc = pcrc(*aptr, divisor, init, xor, 0);
|
||||
if(ptst(crc)) {
|
||||
pfree(&crc);
|
||||
break;
|
||||
} else {
|
||||
pfree(&crc);
|
||||
}
|
||||
}
|
||||
pfree(&xor);
|
||||
if(aptr != eptr) return;
|
||||
|
||||
*result = realloc(*result, ++*resc * sizeof(model_t));
|
||||
if (!*result) {
|
||||
uerror("cannot reallocate result array");
|
||||
return;
|
||||
}
|
||||
*result = realloc(*result, ++*resc * sizeof(model_t));
|
||||
if (!*result) {
|
||||
uerror("cannot reallocate result array");
|
||||
return;
|
||||
}
|
||||
|
||||
rptr = *result + *resc - 1;
|
||||
rptr->spoly = pclone(divisor);
|
||||
rptr->init = pclone(init);
|
||||
rptr->flags = flags;
|
||||
rptr->xorout = pclone(xorout);
|
||||
rptr->check = pzero;
|
||||
rptr->magic = pzero;
|
||||
rptr->name = NULL;
|
||||
rptr = *result + *resc - 1;
|
||||
rptr->spoly = pclone(divisor);
|
||||
rptr->init = pclone(init);
|
||||
rptr->flags = flags;
|
||||
rptr->xorout = pclone(xorout);
|
||||
rptr->check = pzero;
|
||||
rptr->magic = pzero;
|
||||
rptr->name = NULL;
|
||||
|
||||
/* compute check value for this model */
|
||||
mcheck(rptr);
|
||||
/* compute check value for this model */
|
||||
mcheck(rptr);
|
||||
|
||||
/* callback to notify new model */
|
||||
ufound(rptr);
|
||||
/* callback to notify new model */
|
||||
ufound(rptr);
|
||||
}
|
||||
|
||||
@@ -134,9 +134,9 @@ extern void setbmp(void);
|
||||
#define PZERO {0UL, (bmp_t *) 0}
|
||||
|
||||
typedef struct {
|
||||
unsigned long length; /* number of significant bits */
|
||||
bmp_t *bitmap; /* bitmap, MSB first, */
|
||||
/* left-justified in each word */
|
||||
unsigned long length; /* number of significant bits */
|
||||
bmp_t *bitmap; /* bitmap, MSB first, */
|
||||
/* left-justified in each word */
|
||||
} poly_t;
|
||||
|
||||
extern poly_t filtop(FILE *input, unsigned long length, int flags, int bperhx);
|
||||
@@ -181,13 +181,13 @@ extern int pident(const poly_t a, const poly_t b);
|
||||
#define MZERO {PZERO, PZERO, P_BE, PZERO, PZERO, PZERO, NULL}
|
||||
|
||||
typedef struct {
|
||||
poly_t spoly; /* polynomial with highest-order term removed. length determines CRC width */
|
||||
poly_t init; /* initial register value. length == spoly.length */
|
||||
int flags; /* P_REFIN and P_REFOUT indicate reflected input/output */
|
||||
poly_t xorout; /* final register XOR mask. length == spoly.length */
|
||||
poly_t check; /* optional check value, the CRC of the UTF-8 string "123456789" */
|
||||
poly_t magic; /* optional magic check value, the residue of a valid codeword */
|
||||
const char *name; /* optional canonical name of the model */
|
||||
poly_t spoly; /* polynomial with highest-order term removed. length determines CRC width */
|
||||
poly_t init; /* initial register value. length == spoly.length */
|
||||
int flags; /* P_REFIN and P_REFOUT indicate reflected input/output */
|
||||
poly_t xorout; /* final register XOR mask. length == spoly.length */
|
||||
poly_t check; /* optional check value, the CRC of the UTF-8 string "123456789" */
|
||||
poly_t magic; /* optional magic check value, the residue of a valid codeword */
|
||||
const char *name; /* optional canonical name of the model */
|
||||
} model_t;
|
||||
|
||||
extern void mcpy(model_t *dest, const model_t *src);
|
||||
|
||||
Reference in New Issue
Block a user