math.c 6.6 KB

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