base64_from.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include "types.h"
  4. #include "base64.h"
  5. static const u8 base64f[256] = {
  6. //00 01 02 03 04 05 06 07
  7. //08 09 0A 0B 0C 0D 0E 0F
  8. // 0x00..0x3F
  9. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00
  10. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08
  11. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10
  12. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18
  13. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20
  14. 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28
  15. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30
  16. 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38
  17. // 0x40..0x7F
  18. 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40
  19. 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48
  20. 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50
  21. 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58
  22. 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60
  23. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68
  24. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70
  25. 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78
  26. // 0x80..0xBF
  27. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  28. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  29. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  30. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  31. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  32. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  33. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  34. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  35. // 0xC0..0xFF
  36. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  37. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  38. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  39. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  40. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  41. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  42. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  43. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  44. };
  45. size_t base64_from(u8 *dst,const char *src,size_t srclen)
  46. {
  47. if (srclen % 4) {
  48. return -1;
  49. } else if (!srclen) {
  50. return 0;
  51. }
  52. size_t dstlen = BASE64_FROM_LEN(srclen);
  53. dstlen -= (src[srclen - 1] == '=');
  54. dstlen -= (src[srclen - 2] == '=');
  55. for (size_t i = 0, j = 0; i < srclen;) {
  56. u32 sixbits[4];
  57. sixbits[0] = base64f[(unsigned char)src[i++]];
  58. sixbits[1] = base64f[(unsigned char)src[i++]];
  59. sixbits[2] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]);
  60. sixbits[3] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]);
  61. u32 threebytes = 0
  62. | (sixbits[0] << (3 * 6))
  63. | (sixbits[1] << (2 * 6))
  64. | (sixbits[2] << (1 * 6))
  65. | (sixbits[3] << (0 * 6));
  66. if (j < dstlen) dst[j++] = (threebytes >> (2 * 8));
  67. if (j < dstlen) dst[j++] = (threebytes >> (1 * 8)) & 0xff;
  68. if (j < dstlen) dst[j++] = (threebytes >> (0 * 8)) & 0xff;
  69. }
  70. return dstlen;
  71. }
  72. int base64_valid(const char *src,size_t *count)
  73. {
  74. const char *p;
  75. for (p = src;base64f[(u8)*p] != 0xFF;++p)
  76. ;
  77. for (;((size_t) (p - src)) % 4 != 0 && *p == '=';++p)
  78. ;
  79. if (count)
  80. *count = (size_t) (p - src);
  81. return !*p && ((size_t) (p - src)) % 4 == 0;
  82. }