base64.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. namespace base64
  2. {
  3. unsigned char BASE64DECODE[256] =
  4. {
  5. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  6. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  7. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f,
  8. 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0xff,0xff,0xff,0x40,0xff,0xff,
  9. 0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
  10. 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff,
  11. 0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
  12. 0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0xff,0xff,0xff,0xff,
  13. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  14. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  15. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  16. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  17. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  18. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  19. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  20. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
  21. };
  22. void encode(const unsigned char* in,int inlen,unsigned char* out)
  23. {
  24. const char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  25. for (; inlen >= 3; inlen -= 3)
  26. {
  27. *out++ = base64digits[in[0] >> 2];
  28. *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
  29. *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
  30. *out++ = base64digits[in[2] & 0x3f];
  31. in += 3;
  32. }
  33. if (inlen > 0)
  34. {
  35. unsigned char fragment;
  36. *out++ = base64digits[in[0] >> 2];
  37. fragment = (in[0] << 4) & 0x30;
  38. if (inlen > 1)
  39. fragment |= in[1] >> 4;
  40. *out++ = base64digits[fragment];
  41. *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
  42. *out++ = '=';
  43. }
  44. *out = '\0';
  45. }
  46. unsigned char *decode(char *base64code, int base64length, unsigned char *out, int &outlen)
  47. {
  48. unsigned char *pCode = (unsigned char *)base64code;
  49. unsigned char *pBegin = out;
  50. unsigned char *pEnd = out + outlen;
  51. unsigned char uCode;
  52. for (int i = 0; (i < base64length) && (out < pEnd); i++)
  53. {
  54. uCode = BASE64DECODE[pCode[i]];
  55. if (uCode >= 64)
  56. break;
  57. switch( i%4 )
  58. {
  59. case 0:
  60. *out = uCode<<2;
  61. break;
  62. case 1:
  63. *out = *out | (uCode >> 4);
  64. out++;
  65. if (out >= pEnd)
  66. break;
  67. *out = uCode << 4;
  68. break;
  69. case 2:
  70. *out = *out | (uCode >> 2);
  71. out++;
  72. if (out >= pEnd)
  73. break;
  74. *out = uCode << 6;
  75. break;
  76. case 3:
  77. *out = *out | uCode;
  78. out++;
  79. break;
  80. }
  81. }
  82. outlen = out - pBegin;
  83. return pBegin;
  84. }
  85. }