gBase64.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "gBase64.h"
  2. //#include <avr/pgmspace.h>
  3. const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4. "abcdefghijklmnopqrstuvwxyz"
  5. "0123456789+/";
  6. /* 'Private' declarations */
  7. inline void a3_to_a4(unsigned char * a4, unsigned char * a3);
  8. inline void a4_to_a3(unsigned char * a3, unsigned char * a4);
  9. inline unsigned char b64_lookup(char c);
  10. int base64_encode(char *output, char *input, int inputLen) {
  11. int i = 0, j = 0;
  12. int encLen = 0;
  13. unsigned char a3[3];
  14. unsigned char a4[4];
  15. while(inputLen--) {
  16. a3[i++] = *(input++);
  17. if(i == 3) {
  18. a3_to_a4(a4, a3);
  19. for(i = 0; i < 4; i++) {
  20. output[encLen++] = b64_alphabet[a4[i]];
  21. }
  22. i = 0;
  23. }
  24. }
  25. if(i) {
  26. for(j = i; j < 3; j++) {
  27. a3[j] = '\0';
  28. }
  29. a3_to_a4(a4, a3);
  30. for(j = 0; j < i + 1; j++) {
  31. output[encLen++] = b64_alphabet[a4[j]];
  32. }
  33. while((i++ < 3)) {
  34. output[encLen++] = '=';
  35. }
  36. }
  37. output[encLen] = '\0';
  38. return encLen;
  39. }
  40. int base64_decode(char * output, char * input, int inputLen) {
  41. int i = 0, j = 0;
  42. int decLen = 0;
  43. unsigned char a3[3];
  44. unsigned char a4[4];
  45. while (inputLen--) {
  46. if(*input == '=') {
  47. break;
  48. }
  49. a4[i++] = *(input++);
  50. if (i == 4) {
  51. for (i = 0; i <4; i++) {
  52. a4[i] = b64_lookup(a4[i]);
  53. }
  54. a4_to_a3(a3,a4);
  55. for (i = 0; i < 3; i++) {
  56. output[decLen++] = a3[i];
  57. }
  58. i = 0;
  59. }
  60. }
  61. if (i) {
  62. for (j = i; j < 4; j++) {
  63. a4[j] = '\0';
  64. }
  65. for (j = 0; j <4; j++) {
  66. a4[j] = b64_lookup(a4[j]);
  67. }
  68. a4_to_a3(a3,a4);
  69. for (j = 0; j < i - 1; j++) {
  70. output[decLen++] = a3[j];
  71. }
  72. }
  73. output[decLen] = '\0';
  74. return decLen;
  75. }
  76. int base64_enc_len(int plainLen) {
  77. int n = plainLen;
  78. return (n + 2 - ((n + 2) % 3)) / 3 * 4;
  79. }
  80. int base64_dec_len(char * input, int inputLen) {
  81. int i = 0;
  82. int numEq = 0;
  83. for(i = inputLen - 1; input[i] == '='; i--) {
  84. numEq++;
  85. }
  86. return ((6 * inputLen) / 8) - numEq;
  87. }
  88. inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
  89. a4[0] = (a3[0] & 0xfc) >> 2;
  90. a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
  91. a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
  92. a4[3] = (a3[2] & 0x3f);
  93. }
  94. inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
  95. a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
  96. a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
  97. a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
  98. }
  99. inline unsigned char b64_lookup(char c) {
  100. if(c >='A' && c <='Z') return c - 'A';
  101. if(c >='a' && c <='z') return c - 71;
  102. if(c >='0' && c <='9') return c + 4;
  103. if(c == '+') return 62;
  104. if(c == '/') return 63;
  105. return -1;
  106. }