cencode.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 "b64/cencode.h"
  7. void base64_init_encodestate(base64_encodestate* state_in)
  8. {
  9. state_in->step = step_A;
  10. state_in->result = 0;
  11. state_in->stepcount = 0;
  12. }
  13. char base64_encode_value(char value_in)
  14. {
  15. static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  16. if (value_in > 63) return '=';
  17. return encoding[(int)value_in];
  18. }
  19. int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
  20. {
  21. const char* plainchar = plaintext_in;
  22. const char* const plaintextend = plaintext_in + length_in;
  23. char* codechar = code_out;
  24. char result;
  25. char fragment;
  26. result = state_in->result;
  27. switch (state_in->step)
  28. {
  29. while (1)
  30. {
  31. case step_A:
  32. if (plainchar == plaintextend)
  33. {
  34. state_in->result = result;
  35. state_in->step = step_A;
  36. return codechar - code_out;
  37. }
  38. fragment = *plainchar++;
  39. result = (fragment & 0x0fc) >> 2;
  40. *codechar++ = base64_encode_value(result);
  41. result = (fragment & 0x003) << 4;
  42. case step_B:
  43. if (plainchar == plaintextend)
  44. {
  45. state_in->result = result;
  46. state_in->step = step_B;
  47. return codechar - code_out;
  48. }
  49. fragment = *plainchar++;
  50. result |= (fragment & 0x0f0) >> 4;
  51. *codechar++ = base64_encode_value(result);
  52. result = (fragment & 0x00f) << 2;
  53. case step_C:
  54. if (plainchar == plaintextend)
  55. {
  56. state_in->result = result;
  57. state_in->step = step_C;
  58. return codechar - code_out;
  59. }
  60. fragment = *plainchar++;
  61. result |= (fragment & 0x0c0) >> 6;
  62. *codechar++ = base64_encode_value(result);
  63. result = (fragment & 0x03f) >> 0;
  64. *codechar++ = base64_encode_value(result);
  65. ++(state_in->stepcount);
  66. }
  67. }
  68. /* control should not reach here */
  69. return codechar - code_out;
  70. }
  71. int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
  72. {
  73. char* codechar = code_out;
  74. switch (state_in->step)
  75. {
  76. case step_B:
  77. *codechar++ = base64_encode_value(state_in->result);
  78. *codechar++ = '=';
  79. *codechar++ = '=';
  80. break;
  81. case step_C:
  82. *codechar++ = base64_encode_value(state_in->result);
  83. *codechar++ = '=';
  84. break;
  85. case step_A:
  86. break;
  87. }
  88. *codechar++ = '\n';
  89. return codechar - code_out;
  90. }