cencode.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. cencoder.c - c source to a base64 encoding algorithm implementation
  3. This is part of the libb64 project, and has been placed in the public domain.
  4. For details, see http://sourceforge.net/projects/libb64
  5. */
  6. #include "cencode.h"
  7. const int CHARS_PER_LINE = 72;
  8. void base64_init_encodestate(base64_encodestate* state_in)
  9. {
  10. state_in->step = step_A;
  11. state_in->result = 0;
  12. state_in->stepcount = 0;
  13. }
  14. char base64_encode_value(char value_in)
  15. {
  16. static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  17. if (value_in > 63) return '=';
  18. return encoding[(int)value_in];
  19. }
  20. int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
  21. {
  22. const char* plainchar = plaintext_in;
  23. const char* const plaintextend = plaintext_in + length_in;
  24. char* codechar = code_out;
  25. char result;
  26. char fragment;
  27. result = state_in->result;
  28. switch (state_in->step)
  29. {
  30. while (1)
  31. {
  32. case step_A:
  33. if (plainchar == plaintextend)
  34. {
  35. state_in->result = result;
  36. state_in->step = step_A;
  37. return codechar - code_out;
  38. }
  39. fragment = *plainchar++;
  40. result = (fragment & 0x0fc) >> 2;
  41. *codechar++ = base64_encode_value(result);
  42. result = (fragment & 0x003) << 4;
  43. case step_B:
  44. if (plainchar == plaintextend)
  45. {
  46. state_in->result = result;
  47. state_in->step = step_B;
  48. return codechar - code_out;
  49. }
  50. fragment = *plainchar++;
  51. result |= (fragment & 0x0f0) >> 4;
  52. *codechar++ = base64_encode_value(result);
  53. result = (fragment & 0x00f) << 2;
  54. case step_C:
  55. if (plainchar == plaintextend)
  56. {
  57. state_in->result = result;
  58. state_in->step = step_C;
  59. return codechar - code_out;
  60. }
  61. fragment = *plainchar++;
  62. result |= (fragment & 0x0c0) >> 6;
  63. *codechar++ = base64_encode_value(result);
  64. result = (fragment & 0x03f) >> 0;
  65. *codechar++ = base64_encode_value(result);
  66. ++(state_in->stepcount);
  67. if (state_in->stepcount == CHARS_PER_LINE/4)
  68. {
  69. *codechar++ = '\n';
  70. state_in->stepcount = 0;
  71. }
  72. }
  73. }
  74. /* control should not reach here */
  75. return codechar - code_out;
  76. }
  77. int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
  78. {
  79. char* codechar = code_out;
  80. switch (state_in->step)
  81. {
  82. case step_B:
  83. *codechar++ = base64_encode_value(state_in->result);
  84. *codechar++ = '=';
  85. *codechar++ = '=';
  86. break;
  87. case step_C:
  88. *codechar++ = base64_encode_value(state_in->result);
  89. *codechar++ = '=';
  90. break;
  91. case step_A:
  92. break;
  93. }
  94. *codechar++ = '\n';
  95. return codechar - code_out;
  96. }