Skip to content

Instantly share code, notes, and snippets.

@gabrielfern
Last active October 11, 2018 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gabrielfern/8b95e5a3b5351aeab5811124f286c94c to your computer and use it in GitHub Desktop.
Save gabrielfern/8b95e5a3b5351aeab5811124f286c94c to your computer and use it in GitHub Desktop.
Detecção e correção de erro por hamming
#include <assert.h>
/* retorna 0 caso não exista erro
retorna 1 caso exista erro */
int checa_erro(void *dados, unsigned long num_bits) {
unsigned char *array = dados;
unsigned i = 1, j = 0;
while (j < num_bits) {
unsigned k = j+1, l = j;
char acumul = 0;
while (l < num_bits) {
if (k > 0) {
acumul ^= (array[l/8] & (1 << (l % 8))) >> (l%8);
k--;
l++;
} else {
k = j+1;
l += j+1;
}
}
if (acumul)
return 1;
j = (1 << i) - 1;
i++;
}
return 0;
}
void corrige_erro(void *dados, unsigned long num_bits) {
unsigned char *array = dados;
long posicao_erro = -1;
unsigned i = 1, j = 0;
while (j < num_bits) {
unsigned k = j+1, l = j;
char acumul = 0;
while (l < num_bits) {
if (k > 0) {
acumul ^= (array[l/8] & (1 << (l % 8))) >> (l%8);
k--;
l++;
} else {
k = j+1;
l += j+1;
}
}
if (acumul)
posicao_erro += j+1;
j = (1 << i) - 1;
i++;
}
array[posicao_erro/8] ^= 1 << (posicao_erro % 8);
}
int main() {
// 01001011
char bits = 75;
assert(checa_erro(&bits, 8) == 0);
// 01000011
bits = 67;
assert(checa_erro(&bits, 8) == 1);
corrige_erro(&bits, 8);
assert(checa_erro(&bits, 8) == 0);
// 100000101
char dados[] = {5, 1};
assert(checa_erro(dados, 16) == 1);
corrige_erro(dados, 16);
assert(checa_erro(dados, 16) == 0);
// 110000110
dados[0] = 134;
dados[1] = 1;
assert(checa_erro(dados, 16) == 0);
bits = 1;
assert(checa_erro(&bits, 4) == 1);
corrige_erro(&bits, 4);
assert(checa_erro(&bits, 4) == 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment