Advertisement
pasholnahuy

Untitled

Nov 20th, 2023
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.53 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdbool.h>
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9. uint8_t hamming47(uint8_t four_bits) {
  10. return (__builtin_parity(four_bits & 0b1101) << 7) |
  11. (__builtin_parity(four_bits & 0b1011) << 6) |
  12. ((four_bits & 0b1000) << 5) |
  13. (__builtin_parity(four_bits & 0b0111) << 4) |
  14. ((four_bits & 0b0100) << 3) | ((four_bits & 0b0010) << 2) |
  15. ((four_bits & 0b0001) << 1);
  16. }
  17.  
  18. void encode(void *data, void *encoded, size_t n) {
  19. for (size_t i = 0; i < n; ++i) {
  20. uint8_t byte = ((uint8_t *)data)[i];
  21. ((uint8_t *)encoded)[2 * i] = hamming47(byte & 0b1111);
  22. ((uint8_t *)encoded)[2 * i + 1] = hamming47(byte >> 4);
  23. }
  24. }
  25.  
  26. uint8_t hamming_decode(uint8_t enc) {
  27. if (!(__builtin_parity(enc & 0b01100110) |
  28. __builtin_parity(enc & 0b01100110) |
  29. __builtin_parity(enc & 0b00011110))) {
  30. return ((enc & 0b00001110) >> 1) | ((enc & 0b00100000) >> 2);
  31. } else {
  32. int err0 = __builtin_parity(enc & 0b10101010);
  33. int err1 = __builtin_parity(enc & 0b01100110);
  34. int err3 = __builtin_parity(enc & 0b00011110);
  35. int ind = err0 + (err1 << 1) + (err3 << 2) - 1;
  36. uint8_t fixed_enc = enc ^ (ind << 1);
  37. return ((fixed_enc & 0b00001110) >> 1) |
  38. ((fixed_enc & 0b00100000) >> 2);
  39. }
  40. }
  41.  
  42. void decode(void *encoded, void *data, size_t n) {
  43. for (size_t i = 0; i < n; ++i) {
  44. ((uint8_t *)data)[2 * i] = hamming_decode(((uint8_t *)encoded)[2 * i]) |
  45. (hamming_decode(((uint8_t *)encoded)[2 * i + 1]) << 4);
  46. }
  47. }
  48.  
  49. void generate_random_data(void *buffer, size_t n) {
  50. for (size_t i = 0; i < n; ++i) {
  51. ((uint8_t *)buffer)[i] = rand();
  52. }
  53. }
  54.  
  55. void bitflip(void *buffer, size_t n) {
  56. if (rand() % n) {
  57. ((uint8_t *)buffer)[rand() % n] ^= (1 << (rand() % 8));
  58. }
  59. }
  60.  
  61. void test() {
  62. const size_t n = 1000;
  63. void *data = malloc(n);
  64. generate_random_data(data, n);
  65.  
  66. void *encoded_buffer = malloc(2 * n);
  67. encode(data, encoded_buffer, n);
  68. bitflip(encoded_buffer, n);
  69.  
  70. void *decoded_buffer = malloc(n);
  71. decode(encoded_buffer, decoded_buffer, n);
  72. assert(memcmp(data, decoded_buffer, n) == 0);
  73. free(encoded_buffer);
  74. free(data);
  75. free(decoded_buffer);
  76. }
  77.  
  78. int main() {
  79. size_t counter = 0;
  80. for (int _ = 0; _ < 1000; ++_) {
  81. test();
  82. printf("%zu tests passed...\n", ++counter);
  83. }
  84. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement