util.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  28. /*
  29. simple base64 decoder, not particularly efficient, but small
  30. */
  31. int32_t base64_decode(const char *s, uint8_t *out, const uint32_t max_len)
  32. {
  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. }
  66. /*
  67. encode as base64, returning allocated string
  68. */
  69. char *base64_encode(const uint8_t *d, int len)
  70. {
  71. uint32_t bit_offset, byte_offset, idx, i;
  72. uint32_t bytes = (len*8 + 5)/6;
  73. uint32_t pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
  74. char *out = new char[bytes+pad_bytes+1];
  75. if (!out) {
  76. return nullptr;
  77. }
  78. for (i=0;i<bytes;i++) {
  79. byte_offset = (i*6)/8;
  80. bit_offset = (i*6)%8;
  81. if (bit_offset < 3) {
  82. idx = (d[byte_offset] >> (2-bit_offset)) & 0x3FU;
  83. } else {
  84. idx = (d[byte_offset] << (bit_offset-2)) & 0x3FU;
  85. if (byte_offset+1 < len) {
  86. idx |= (d[byte_offset+1] >> (8-(bit_offset-2)));
  87. }
  88. }
  89. out[i] = b64[idx];
  90. }
  91. for (;i<bytes+pad_bytes;i++) {
  92. out[i] = '=';
  93. }
  94. out[i] = 0;
  95. return out;
  96. }