int gpmi_verify_hamming_13_8(void *data, u8 *parity, size_t size) { int i; u8 *pdata = data; int bit_to_flip; u8 np, syndrome; int errors = 0; for (i = 0; i < size; i ++, pdata++) { np = calculate_parity(*pdata); syndrome = np ^ parity[i]; if (syndrome == 0) /* cool */ { continue; } if (even_number_of_1s(syndrome)) return -i; /* can't recover */ bit_to_flip = lookup_single_error(syndrome); if (bit_to_flip < 0) return -i; /* can't fix the error */ if (bit_to_flip < 8) { *pdata ^= (1 << bit_to_flip); errors++; } } return errors; }
void gpmi_encode_hamming_13_8(void *source_block, size_t src_size, void *source_ecc, size_t ecc_size) { int i; u8 *src = source_block; u8 *ecc = source_ecc; for (i = 0; i < src_size && i < ecc_size; i++) ecc[i] = calculate_parity(src[i]); }
int *bad_parity(char* string) { int i=0, j=0, len=strlen(string); int *bad_parity = (int *)malloc(sizeof(int)); char *check = (char*)malloc(len*sizeof(char)); bad_parity[0] = bad_parity[1] = -1; strncpy(check, string, len); calculate_parity(check); //printf("[•] parity_ck '%s' (len:%d)\n",check,(int)strlen(check)); // compare all parity bits for(i=0; i<len; i++) { if (power_of_2(i+1) && string[i] != check[i]) { int *tmp = (int *)realloc(bad_parity, j+1*sizeof(int)); if (tmp) {bad_parity = tmp;} bad_parity[j] = i; bad_parity[j+1] = -1; j++; } } free(check); return bad_parity; }
int main (int argc, char *argv[], char *arge[]) { if (argc < 2) { print_usage(); return 0; } // check if argv[1] is a binary string if (!check_binary(argv[1])) { fprintf(stderr, "%s is not a binary string\n", argv[1]); return -1; } // init rand() srand(time(NULL)); // copy the argv[1] message // calculate final message length // so we don't need to realloc it everytime int len = strlen(argv[1]); int parity_len = 2; for (int i = 0; i<=len; i++) { //printf("t:%d - %s\n",t,power_of_2(t+1) ? "YES" : "NO"); parity_len++; if (power_of_2(parity_len)) { parity_len++; } } printf("F2^%d -> F2^%d\n",len, parity_len-1); char *message = (char*)malloc(parity_len*sizeof(char)); strncpy(message, argv[1], len+1); // print the raw binary message printf("[•] encoding '%s' (len:%d)\n",message,len); // then add spaces for parity bits // and calculate them add_parity_space(message); calculate_parity(message); printf("[•] sent '%s' (len:%d)\n",message,(int)strlen(message)); // copy the message and alter one bit char *bad = (char*)malloc(strlen(message)*sizeof(char)); strncpy(bad, message, strlen(message)); alter_a_bit(bad); // print altered message printf("[•] recieve '%s' (len:%d)\n",bad,(int)strlen(bad)); // check parity to correct the altered message int *bad_bits = bad_parity(bad); int i = 0, sum=0; printf("[?] corrupted parity bits :"); while (bad_bits[i] != -1) { sum+=bad_bits[i]+1; printf(" %d",bad_bits[i]+1); i++; } printf("\n"); printf("[?] fixed data bit at index %d\n",sum); free(bad_bits); // correct if necessary if (sum>0) { bad[sum-1] = (bad[sum-1] == '0') ? '1' : '0'; printf("[•] corrected '%s' (len:%d)\n",bad,(int)strlen(bad)); }else { printf("[•] already_ok '%s' (len:%d)\n",bad,(int)strlen(bad)); } // remove the parity bits remove_parity_space(bad); printf("[•] decoding '%s' (len:%d)\n",bad,(int)strlen(bad)); // compare with original message printf("[•] %s\n",strncmp(argv[1],bad,len) == 0 ? "message successfully decoded" : "failed to decode message"); //printf(" in: '%s'\n",argv[1]); //printf("out: '%s'\n",bad); // free memory space free(message); free(bad); return 0; }