base64_decode_atom.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /*
  2. * Core routine to decode a single atomic base64 chunk.
  3. */
  4. #include "defs.h"
  5. #include "misc.h"
  6. int base64_decode_atom(const char *atom, unsigned char *out)
  7. {
  8. int vals[4];
  9. int i, v, len;
  10. unsigned word;
  11. char c;
  12. for (i = 0; i < 4; i++) {
  13. c = atom[i];
  14. if (c >= 'A' && c <= 'Z')
  15. v = c - 'A';
  16. else if (c >= 'a' && c <= 'z')
  17. v = c - 'a' + 26;
  18. else if (c >= '0' && c <= '9')
  19. v = c - '0' + 52;
  20. else if (c == '+')
  21. v = 62;
  22. else if (c == '/')
  23. v = 63;
  24. else if (c == '=')
  25. v = -1;
  26. else
  27. return 0; /* invalid atom */
  28. vals[i] = v;
  29. }
  30. if (vals[0] == -1 || vals[1] == -1)
  31. return 0;
  32. if (vals[2] == -1 && vals[3] != -1)
  33. return 0;
  34. if (vals[3] != -1)
  35. len = 3;
  36. else if (vals[2] != -1)
  37. len = 2;
  38. else
  39. len = 1;
  40. word = ((vals[0] << 18) |
  41. (vals[1] << 12) | ((vals[2] & 0x3F) << 6) | (vals[3] & 0x3F));
  42. out[0] = (word >> 16) & 0xFF;
  43. if (len > 1)
  44. out[1] = (word >> 8) & 0xFF;
  45. if (len > 2)
  46. out[2] = word & 0xFF;
  47. return len;
  48. }