#include #include #include // CRC16 // Generatorpolynom x^16+x^12+x^5+1 = (1) 0001 0000 0010 0001 = 0x(1)1021 #define CRC 16 #define CODELEN_CRC 1024 //(2*0xDF) unsigned char msg[CODELEN_CRC], par[8]; char bitstr[CODELEN_CRC*8+1+32*8]; char g16[] = "10001000000100001"; // big endian unsigned int crc16poly = 0x1021; unsigned int crc16init = 0xFFFF; // 16bit // BCH-Code (63,51) // Generatorpolynom x^12+x^10+x^8+x^5+x^4+x^3+1 #define BCH 46 #define CODELEN_BCH 46 char g12[] = "1010100111001"; // big endian char *g = NULL; int msglen, parlen; int option = 0; int check(char *str) { while (*str) { //printf("%02X ", *str); if (*str < 0x30 || *str > 0x31) return -1; str++; } //printf("\n"); return 0; } int deg(char *x) { int i; i = strlen(x); while (*x && *x == '0') { x++; i--; } return i-1; } char *shortstr(char *x) { if (strlen(x) <= 1) return x; while (strlen(x) > 1 && *x == '0') x++; return x; } int polymodcheck(char *x) { int i, j, d; char *t = malloc(strlen(x)+1); char *taddr = t; t[0] = '\0'; for (i = 0; i < strlen(x)+1; i++) t[i] = x[i]; t = shortstr(t); d = strlen(t); printf("%s\n", t); printf("%s\n", g); while (deg(t) >= deg(g)) { for (i = 0; i < strlen(g); i++) { if (t[i] == g[i]) t[i] = '0'; else t[i] = '1'; } t = shortstr(t); for (j = 0; j < d-strlen(t); j++) printf(" "); printf("%s\n", t); if (t[0] == '0') return 0; for (j = 0; j < d-strlen(t); j++) printf(" "); printf("%s\n", g); } printf("%s\n", t); free(taddr); return 1; } unsigned int crc16(unsigned char bytes[], int len) { unsigned int rem = crc16init; // init value int i, j; for (i = 0; i < len; i++) { rem = rem ^ (bytes[i] << 8); for (j = 0; j < 8; j++) { if (rem & 0x8000) { rem = (rem << 1) ^ crc16poly; } else { rem = (rem << 1); } rem &= 0xFFFF; } } return rem; } int main(int argc, char *argv[]) { char *str; int i, j, rem, byt; if (argv[1]) { if (strcmp(argv[1], "--crc") == 0) option = CRC; if (strcmp(argv[1], "--bch") == 0) option = BCH; } if (!argv[1] || !option) { fprintf(stderr, "%s --crc [crc]\n", argv[0]); fprintf(stderr, "%s --bch \n", argv[0]); return 0; } str = argv[2]; if (option == CRC) { msglen = strlen(str)/2; if (msglen > CODELEN_CRC) { fprintf(stderr, "len > %d\n", CODELEN_CRC); return -3; } for (i = 0; i < msglen; i++) sscanf(argv[2]+2*i, "%2hhx", msg+i); rem = crc16(msg, msglen); printf("%04X\n", rem); g = g16; parlen = (strlen(g)-1)/8; for (i = 0; i < msglen; i++) { byt = msg[i]; if (i < 2) byt ^= (crc16init >> (8*(1-i))) & 0xFF; // init value 0xFFFF for (j = 0; j < 8; j++) { bitstr[8*i+7-j] = (byt & 0x1) + 0x30; byt >>= 1; } } // wenn crc nicht angehaengt, dann x^n shiften: for (i = 0; i < 8*parlen; i++) bitstr[8*msglen+i] = 0x30; if (argv[3] && strlen(argv[3])/2 == parlen) { for (i = 0; i < parlen; i++) { sscanf(argv[3]+2*i, "%2hhx", par+i); byt = par[i]; for (j = 0; j < 8; j++) { bitstr[8*(msglen+parlen-1-i)+7-j] = (byt & 0x1) + 0x30; byt >>= 1; } } } /* for (i = 0; i < msglen; i++) printf("%02X ", msg[i]); printf(" "); for (i = 0; i < parlen; i++) printf("%02X ", par[i]); printf("\n"); */ str = shortstr(bitstr); } else if (option == BCH) { if (strlen(str) > CODELEN_BCH) { printf("CODELEN\n"); return -3; } str = shortstr(str); if (check(str)) { printf("nicht in GF(2)[X]\n"); return -1; } //printf("f = %s\n", str); //printf("deg(f) = %d\n", deg(str)); g = g12; } //if (option != CRC) polymodcheck(str); return 0; }