Advertisement
pasholnahuy

Untitled

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