hamming.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "hamming.h"
  2. #include "math.h"
  3. #include <stdbool.h>
  4. #include <string.h>
  5. //编码
  6. unsigned char HMBM_74(unsigned char a)
  7. {
  8. unsigned char b =0;
  9. b = a & 0x0F;
  10. b = b <<0x03;
  11. if(b&0x08){b=b^0x03;}
  12. if(b&0x10){b=b^0x05;}
  13. if(b&0x20){b=b^0x06;}
  14. if(b&0x40){b=b^0x07;}
  15. return(b & 0x7F);
  16. }
  17. //解码
  18. unsigned char HMYM_74(unsigned char a)
  19. {
  20. unsigned char b=0,c=0;
  21. b = a;
  22. c = 0;
  23. if(b&0x40) {c = c^0x07 ;}
  24. if(b&0x20) {c = c^0x06 ;}
  25. if(b&0x10) {c = c^0x05 ;}
  26. if(b&0x08) {c = c^0x03 ;}
  27. if(b&0x04) {c = c^0x04 ;}
  28. if(b&0x02) {c = c^0x02 ;}
  29. if(b&0x01) {c = c^0x01 ;}
  30. switch(c){
  31. case 0 :b = b >> 3 ;break ;
  32. case 1 :b = b >> 3 ;break ;
  33. case 2 :b = b >> 3 ;break ;
  34. case 3 :b = (b^0x08) >> 3 ;break ;
  35. case 4 :b = b >> 3 ;break ;
  36. case 5 :b = (b^0x10) >> 3 ;break ;
  37. case 6 :b = (b^0x20) >> 3 ;break ;
  38. case 7 :b = (b^0x40) >> 3 ;break ;
  39. }
  40. return (b & 0x0F);
  41. }
  42. //对u32数据编码
  43. //data:输入的待编码数据
  44. //code:编码后生成的数据(1字节的原始数据生成2字节的编码数据)
  45. void HM_encode_u32(uint32_t data, uint32_t *code)
  46. {
  47. int i,j;
  48. uint32_t temp = 0;
  49. uint8_t data_char[8] = {0};
  50. uint8_t data_encode[8] = {0};
  51. memset(code,0,2);
  52. // 原始数据拆分:
  53. for(i = 0; i < 8; i++)
  54. {
  55. data_char[i] = (data>>(4*(7-i))) & 0x0f;
  56. }
  57. //编码
  58. for(i = 0; i < 8; i++)
  59. {
  60. data_encode[i] = HMBM_74(data_char[i]);
  61. }
  62. //编码后数据合成
  63. for(i = 0; i < 2; i++)
  64. {
  65. for(j = 0; j < 4; j++)
  66. {
  67. temp = data_encode[i*4+j];
  68. code[i] |= temp<<(3-j)*8;
  69. }
  70. }
  71. }
  72. //对u32数据解码
  73. uint32_t HM_decode_u32(uint32_t *data)
  74. {
  75. int i,j;
  76. uint32_t temp = 0;
  77. uint32_t data_de=0;
  78. uint8_t data_temp[8] = {0};
  79. uint8_t data_decode[8] = {0};
  80. // 原始数据拆分:
  81. for(i = 0; i < 2; i++)
  82. {
  83. for(j = 0; j < 4; j++)
  84. {
  85. data_temp[i*4+j] = (data[i]>>(3-j)*8) & 0xff;
  86. }
  87. }
  88. //解码
  89. for(i = 0; i < 8; i++)
  90. {
  91. data_decode[i] = HMYM_74(data_temp[i]);
  92. }
  93. //解码后数据合成
  94. for(i = 0; i < 8; i++)
  95. {
  96. temp = data_decode[i];
  97. data_de |= temp<<4*(7-i);
  98. }
  99. return data_de;
  100. }
  101. //汉明码编码(一个字节)
  102. void HM_encode_char(uint8_t data, uint8_t *code)
  103. {
  104. int i;
  105. uint8_t data_char[2] = {0};
  106. memset(code,0,2);
  107. // 原始数据拆分:
  108. data_char[0] = data & 0x0f;
  109. data_char[1] = (data>>4) & 0x0f;
  110. //编码
  111. for(i = 0; i < 2; i++)
  112. {
  113. code[i] = HMBM_74(data_char[i]);
  114. }
  115. }
  116. //汉明码解码(一个字节)
  117. uint8_t HM_decode_char(uint8_t *code)
  118. {
  119. int i;
  120. uint8_t data = 0;
  121. uint8_t data_decode[2] = {0};
  122. //解码
  123. for(i = 0; i < 2; i++)
  124. {
  125. data_decode[i] = HMYM_74(code[i]);
  126. }
  127. //解码后数据合成
  128. data |= data_decode[0];
  129. data |= data_decode[1]<<4;
  130. return data;
  131. }
  132. //汉明码编码(多字节)
  133. //返回编码后的字节数
  134. void HM_encode(uint8_t *src, uint8_t *des, uint16_t size)
  135. {
  136. int i;
  137. memset(des,0,size*2);
  138. for(i = 0; i < size; i++)
  139. {
  140. HM_encode_char(src[i],des+2*i);
  141. }
  142. }
  143. //汉明码解码(多个字节)
  144. void HM_decode(uint8_t *src, uint8_t *des, uint16_t size)
  145. {
  146. int i;
  147. memset(des,0,size/2);
  148. for(i = 0; i < size; i=i+2)
  149. {
  150. des[i/2] = HM_decode_char(src+i);
  151. }
  152. }
  153. #define NUM 8
  154. void hamming_test(uint8_t num)
  155. {
  156. #if 0
  157. int i,j,temp,temp_bit;
  158. unsigned char coder_T[NUM] = {0};
  159. unsigned char encoder_T[NUM] = {0};
  160. unsigned char decoder_T[NUM] = {0};
  161. srand(TickCounter);
  162. printf("汉明码测试:\n");
  163. printf("原始数据:");
  164. //生成原数据
  165. for(i = 0; i < NUM; i++)
  166. {
  167. coder_T[i] = rand()%0x10;
  168. printf("%02x ",coder_T[i]);
  169. }
  170. printf("\n");
  171. //编码
  172. for(i = 0; i < NUM; i++)
  173. {
  174. encoder_T[i] = HMBM_74(coder_T[i]);
  175. }
  176. printf("编码数据:");
  177. for(i = 0; i < NUM; i++)
  178. {
  179. printf("%02x ",encoder_T[i]);
  180. }
  181. printf("\n");
  182. printf("共修改%d位\n",num);
  183. for(i = 0; i < num; i++)
  184. {
  185. temp = rand()%(NUM*8);
  186. j = temp/8;
  187. temp_bit = temp%8;
  188. encoder_T[j] ^= 1<<temp_bit;
  189. printf("修改第%02d位\n",temp);
  190. }
  191. printf("修改数据:");
  192. for(i = 0; i < NUM; i++)
  193. {
  194. printf("%02x ",encoder_T[i]);
  195. }
  196. printf("\n");
  197. //解码
  198. for(i = 0; i < NUM; i++)
  199. {
  200. decoder_T[i] = HMYM_74(encoder_T[i]);
  201. }
  202. printf("解码数据:");
  203. for(i = 0; i < NUM; i++)
  204. {
  205. printf("%02x ",decoder_T[i]);
  206. }
  207. printf("\n");
  208. #endif
  209. uint32_t data = 0, data_de = 0;
  210. uint32_t data_en[2] = {0};
  211. srand(0);
  212. printf("汉明码测试:\n");
  213. data = rand()%0xffffffff;
  214. printf("原始数据:%08x\n",data);
  215. HM_encode_u32(data,data_en);
  216. printf("编码数据:%08x, %08x\n",data_en[0],data_en[1]);
  217. data_de = HM_decode_u32(data_en);
  218. printf("解码数据:%08x\n",data_de);
  219. }