util.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #include "util.h"
  2. #include <string.h>
  3. /*
  4. 64 bit crc from ArduPilot
  5. */
  6. uint64_t crc_crc64(const uint32_t *data, uint16_t num_words)
  7. {
  8. const uint64_t poly = 0x42F0E1EBA9EA3693ULL;
  9. uint64_t crc = ~(0ULL);
  10. while (num_words--) {
  11. uint32_t value = *data++;
  12. for (uint8_t j = 0; j < 4; j++) {
  13. uint8_t byte = ((uint8_t *)&value)[j];
  14. crc ^= (uint64_t)byte << 56u;
  15. for (uint8_t i = 0; i < 8; i++) {
  16. if (crc & (1ull << 63u)) {
  17. crc = (uint64_t)(crc << 1u) ^ poly;
  18. } else {
  19. crc = (uint64_t)(crc << 1u);
  20. }
  21. }
  22. }
  23. }
  24. crc ^= ~(0ULL);
  25. return crc;
  26. }
  27. /*
  28. simple base64 decoder, not particularly efficient, but small
  29. */
  30. int32_t base64_decode(const char *s, uint8_t *out, const uint32_t max_len)
  31. {
  32. static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  33. const char *p;
  34. uint32_t n = 0;
  35. uint32_t i = 0;
  36. while (*s && (p=strchr(b64,*s))) {
  37. const uint8_t idx = (p - b64);
  38. const uint32_t byte_offset = (i*6)/8;
  39. const uint32_t bit_offset = (i*6)%8;
  40. out[byte_offset] &= ~((1<<(8-bit_offset))-1);
  41. if (bit_offset < 3) {
  42. if (byte_offset >= max_len) {
  43. break;
  44. }
  45. out[byte_offset] |= (idx << (2-bit_offset));
  46. n = byte_offset+1;
  47. } else {
  48. if (byte_offset >= max_len) {
  49. break;
  50. }
  51. out[byte_offset] |= (idx >> (bit_offset-2));
  52. n = byte_offset+1;
  53. if (byte_offset+1 >= max_len) {
  54. break;
  55. }
  56. out[byte_offset+1] = (idx << (8-(bit_offset-2))) & 0xFF;
  57. n = byte_offset+2;
  58. }
  59. s++; i++;
  60. }
  61. if ((n > 0) && (*s == '=')) {
  62. n -= 1;
  63. }
  64. return n;
  65. }