Base64.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright 2009, Pier Luigi Fiorini.
  3. * Copyright 2004-2009, René Nyffenegge
  4. * Distributed under the terms of the MIT License.
  5. */
  6. // Based on original code from:
  7. // http://www.adp-gmbh.ch/cpp/common/base64.html
  8. #include <ctype.h>
  9. #include "Base64.h"
  10. static const BString chars =
  11. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  12. "abcdefghijklmnopqrstuvwxyz"
  13. "0123456789+/";
  14. Base64::Base64()
  15. {
  16. }
  17. BString
  18. Base64::Encode(const uchar* data, size_t length)
  19. {
  20. BString encoded;
  21. int32 i = 0;
  22. uchar array3[3], array4[4];
  23. while (length--) {
  24. array3[i++] = *(data++);
  25. if (i == 3) {
  26. array4[0] = (uchar)((array3[0] & 0xfc) >> 2);
  27. array4[1] = (uchar)(((array3[0] & 0x03) << 4) + ((array3[1] & 0xf0) >> 4));
  28. array4[2] = (uchar)(((array3[1] & 0x0f) << 2) + ((array3[2] & 0xc0) >> 6));
  29. array4[3] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
  30. for (i = 0; i < 3; i++)
  31. encoded += array3[i];
  32. i = 0;
  33. }
  34. }
  35. if (i) {
  36. for (int32 j = i; j < 4; j++)
  37. array4[j] = 0;
  38. for (int32 j = 0; j < 4; j++)
  39. array4[j] = (uchar)chars.FindFirst(array4[j]);
  40. array3[0] = (uchar)((array4[0] << 2) + ((array4[i] & 0x30) >> 4));
  41. array3[1] = (uchar)(((array4[1] & 0xf) << 4) + ((array4[2] & 0x3c) >> 2));
  42. array3[2] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
  43. for (int32 j = 0; j < i - 1; j++)
  44. encoded += array3[j];
  45. }
  46. return encoded;
  47. }
  48. bool
  49. Base64::IsBase64(uchar c)
  50. {
  51. return isalnum(c) || (c == '+') || (c == '/');
  52. }
  53. BString
  54. Base64::Decode(const BString& data)
  55. {
  56. int32 length = data.Length();
  57. int32 i = 0;
  58. int32 index = 0;
  59. uchar array4[4], array3[3];
  60. BString decoded;
  61. while (length-- && (data[index] != '=') && IsBase64(data[index])) {
  62. array4[i++] = data[index];
  63. index++;
  64. if (i == 4) {
  65. for (i = 0; i < 4; i++)
  66. array4[i] = (uchar)chars.FindFirst(array4[i]);
  67. array3[0] = (uchar)((array4[0] << 2) + ((array4[1] & 0x30)>> 4));
  68. array3[1] = (uchar)(((array4[1] & 0xf) << 4) + ((array4[2] & 0x3c) >> 2));
  69. array3[2] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
  70. for (i = 0; i < 3; i++)
  71. decoded += array3[i];
  72. i = 0;
  73. }
  74. }
  75. if (i) {
  76. int32 j;
  77. for (j = i; j < 4; j++)
  78. array4[j] = 0;
  79. for (j = 0; j < 4; j++)
  80. array4[j] = (uchar)chars.FindFirst(array4[j]);
  81. array3[0] = (uchar)((array4[0] << 2) + ((array4[1] & 0x30) >> 4));
  82. array3[1] = (uchar)(((array4[1] & 0xf) << 4) + ((array4[2] & 0x3c) >> 2));
  83. array3[2] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
  84. for (j = 0; j < i - 1; j++)
  85. decoded += array3[j];
  86. }
  87. return decoded;
  88. }