math.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "math.h"
  2. uint64_t subghz_protocol_blocks_reverse_key(uint64_t key, uint8_t count_bit) {
  3. uint64_t key_reverse = 0;
  4. for(uint8_t i = 0; i < count_bit; i++) {
  5. key_reverse = key_reverse << 1 | bit_read(key, i);
  6. }
  7. return key_reverse;
  8. }
  9. uint8_t subghz_protocol_blocks_get_parity(uint64_t key, uint8_t count_bit) {
  10. uint8_t parity = 0;
  11. for(uint8_t i = 0; i < count_bit; i++) {
  12. parity += bit_read(key, i);
  13. }
  14. return parity & 0x01;
  15. }
  16. uint8_t subghz_protocol_blocks_crc4(
  17. uint8_t const message[],
  18. unsigned nBytes,
  19. uint8_t polynomial,
  20. uint8_t init) {
  21. unsigned remainder = init << 4; // LSBs are unused
  22. unsigned poly = polynomial << 4;
  23. unsigned bit;
  24. while(nBytes--) {
  25. remainder ^= *message++;
  26. for(bit = 0; bit < 8; bit++) {
  27. if(remainder & 0x80) {
  28. remainder = (remainder << 1) ^ poly;
  29. } else {
  30. remainder = (remainder << 1);
  31. }
  32. }
  33. }
  34. return remainder >> 4 & 0x0f; // discard the LSBs
  35. }
  36. uint8_t subghz_protocol_blocks_crc7(
  37. uint8_t const message[],
  38. unsigned nBytes,
  39. uint8_t polynomial,
  40. uint8_t init) {
  41. unsigned remainder = init << 1; // LSB is unused
  42. unsigned poly = polynomial << 1;
  43. unsigned byte, bit;
  44. for(byte = 0; byte < nBytes; ++byte) {
  45. remainder ^= message[byte];
  46. for(bit = 0; bit < 8; ++bit) {
  47. if(remainder & 0x80) {
  48. remainder = (remainder << 1) ^ poly;
  49. } else {
  50. remainder = (remainder << 1);
  51. }
  52. }
  53. }
  54. return remainder >> 1 & 0x7f; // discard the LSB
  55. }
  56. uint8_t subghz_protocol_blocks_crc8(
  57. uint8_t const message[],
  58. unsigned nBytes,
  59. uint8_t polynomial,
  60. uint8_t init) {
  61. uint8_t remainder = init;
  62. unsigned byte, bit;
  63. for(byte = 0; byte < nBytes; ++byte) {
  64. remainder ^= message[byte];
  65. for(bit = 0; bit < 8; ++bit) {
  66. if(remainder & 0x80) {
  67. remainder = (remainder << 1) ^ polynomial;
  68. } else {
  69. remainder = (remainder << 1);
  70. }
  71. }
  72. }
  73. return remainder;
  74. }
  75. uint8_t subghz_protocol_blocks_crc8le(
  76. uint8_t const message[],
  77. unsigned nBytes,
  78. uint8_t polynomial,
  79. uint8_t init) {
  80. uint8_t remainder = subghz_protocol_blocks_reverse_key(init, 8);
  81. unsigned byte, bit;
  82. polynomial = subghz_protocol_blocks_reverse_key(polynomial, 8);
  83. for(byte = 0; byte < nBytes; ++byte) {
  84. remainder ^= message[byte];
  85. for(bit = 0; bit < 8; ++bit) {
  86. if(remainder & 1) {
  87. remainder = (remainder >> 1) ^ polynomial;
  88. } else {
  89. remainder = (remainder >> 1);
  90. }
  91. }
  92. }
  93. return remainder;
  94. }
  95. uint16_t subghz_protocol_blocks_crc16lsb(
  96. uint8_t const message[],
  97. unsigned nBytes,
  98. uint16_t polynomial,
  99. uint16_t init) {
  100. uint16_t remainder = init;
  101. unsigned byte, bit;
  102. for(byte = 0; byte < nBytes; ++byte) {
  103. remainder ^= message[byte];
  104. for(bit = 0; bit < 8; ++bit) {
  105. if(remainder & 1) {
  106. remainder = (remainder >> 1) ^ polynomial;
  107. } else {
  108. remainder = (remainder >> 1);
  109. }
  110. }
  111. }
  112. return remainder;
  113. }
  114. uint16_t subghz_protocol_blocks_crc16(
  115. uint8_t const message[],
  116. unsigned nBytes,
  117. uint16_t polynomial,
  118. uint16_t init) {
  119. uint16_t remainder = init;
  120. unsigned byte, bit;
  121. for(byte = 0; byte < nBytes; ++byte) {
  122. remainder ^= message[byte] << 8;
  123. for(bit = 0; bit < 8; ++bit) {
  124. if(remainder & 0x8000) {
  125. remainder = (remainder << 1) ^ polynomial;
  126. } else {
  127. remainder = (remainder << 1);
  128. }
  129. }
  130. }
  131. return remainder;
  132. }
  133. uint8_t subghz_protocol_blocks_lfsr_digest8(
  134. uint8_t const message[],
  135. unsigned bytes,
  136. uint8_t gen,
  137. uint8_t key) {
  138. uint8_t sum = 0;
  139. for(unsigned k = 0; k < bytes; ++k) {
  140. uint8_t data = message[k];
  141. for(int i = 7; i >= 0; --i) {
  142. // XOR key into sum if data bit is set
  143. if((data >> i) & 1) sum ^= key;
  144. // roll the key right (actually the lsb is dropped here)
  145. // and apply the gen (needs to include the dropped lsb as msb)
  146. if(key & 1)
  147. key = (key >> 1) ^ gen;
  148. else
  149. key = (key >> 1);
  150. }
  151. }
  152. return sum;
  153. }
  154. uint8_t subghz_protocol_blocks_lfsr_digest8_reflect(
  155. uint8_t const message[],
  156. int bytes,
  157. uint8_t gen,
  158. uint8_t key) {
  159. uint8_t sum = 0;
  160. // Process message from last byte to first byte (reflected)
  161. for(int k = bytes - 1; k >= 0; --k) {
  162. uint8_t data = message[k];
  163. // Process individual bits of each byte (reflected)
  164. for(int i = 0; i < 8; ++i) {
  165. // XOR key into sum if data bit is set
  166. if((data >> i) & 1) {
  167. sum ^= key;
  168. }
  169. // roll the key left (actually the lsb is dropped here)
  170. // and apply the gen (needs to include the dropped lsb as msb)
  171. if(key & 0x80)
  172. key = (key << 1) ^ gen;
  173. else
  174. key = (key << 1);
  175. }
  176. }
  177. return sum;
  178. }
  179. uint16_t subghz_protocol_blocks_lfsr_digest16(
  180. uint8_t const message[],
  181. unsigned bytes,
  182. uint16_t gen,
  183. uint16_t key) {
  184. uint16_t sum = 0;
  185. for(unsigned k = 0; k < bytes; ++k) {
  186. uint8_t data = message[k];
  187. for(int i = 7; i >= 0; --i) {
  188. // if data bit is set then xor with key
  189. if((data >> i) & 1) sum ^= key;
  190. // roll the key right (actually the lsb is dropped here)
  191. // and apply the gen (needs to include the dropped lsb as msb)
  192. if(key & 1)
  193. key = (key >> 1) ^ gen;
  194. else
  195. key = (key >> 1);
  196. }
  197. }
  198. return sum;
  199. }
  200. uint8_t subghz_protocol_blocks_add_bytes(uint8_t const message[], size_t num_bytes) {
  201. int result = 0;
  202. for(size_t i = 0; i < num_bytes; ++i) {
  203. result += message[i];
  204. }
  205. return (uint8_t)result;
  206. }
  207. int subghz_protocol_blocks_parity8(uint8_t byte) {
  208. byte ^= byte >> 4;
  209. byte &= 0xf;
  210. return (0x6996 >> byte) & 1;
  211. }
  212. int subghz_protocol_blocks_parity_bytes(uint8_t const message[], size_t num_bytes) {
  213. int result = 0;
  214. for(size_t i = 0; i < num_bytes; ++i) {
  215. result ^= subghz_protocol_blocks_parity8(message[i]);
  216. }
  217. return result;
  218. }
  219. uint8_t subghz_protocol_blocks_xor_bytes(uint8_t const message[], size_t num_bytes) {
  220. uint8_t result = 0;
  221. for(size_t i = 0; i < num_bytes; ++i) {
  222. result ^= message[i];
  223. }
  224. return result;
  225. }