fork download
  1. // Base64EnDe.cpp : アプリケーションのエントリ ポイントを定義します。
  2. //
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. #include <cstdint>
  7. #include <tuple>
  8.  
  9.  
  10. typedef std::vector<std::uint8_t> DType;
  11. const std::string Token = "ABCDEFGHIJKLNMOPQRSTUVWXYZabcdefghijklnmopqrstuvwxyz0123456789+/";
  12. const std::string Pad = "=";
  13.  
  14. DType Char3Enc4(const char& A, const char& B, const char& C) {
  15. std::uint64_t V1 = 0;
  16. std::uint64_t V2 = 0;
  17. std::uint64_t P = 0;
  18. DType D;
  19. D.reserve(4);
  20. V1 = A;
  21. P = (V1 >> 2) & 0x3f;
  22. D.push_back(P);
  23. V1 &= 3;
  24. V2 = (B<0) ? 0:B;
  25.  
  26. P = ((V1 << 4) & 0x3f) | ((V2 >> 4) & 0x3f);
  27. D.push_back(P);
  28. V1 = V2 - ((V2 >> 4) << 4);
  29. V2 = (C<0) ? 0:C;
  30.  
  31. if (B < 0) return D;
  32.  
  33. P = ((V1 << 2) & 0x3f) | ((V2 >> 6) & 0x3f);
  34. D.push_back(P);
  35. V1 = V2 - ((V2 >> 6) << 6);
  36.  
  37. if (C < 0) return D;
  38.  
  39. P = V1 & 0x3f;
  40. D.push_back(P);
  41.  
  42. return D;
  43. }
  44.  
  45.  
  46. std::string Base64Enc(const std::string& s) {
  47.  
  48. DType D;
  49. DType T;
  50. std::string R;
  51. char A = 0;
  52. char B = 0;
  53. char C = 0;
  54.  
  55.  
  56. for (std::size_t i = 0; i < s.size(); i+=3) {
  57. A = i < s.size() ? s[i]:-1;
  58. B = i+1 < s.size() ? s[i+1]:-1;
  59. C = i+2 < s.size() ? s[i+2]:-1;
  60.  
  61. T = Char3Enc4(A, B, C);
  62. D.insert(D.begin()+D.size(), T.begin(), T.end());
  63. }
  64.  
  65. for (auto& o : D) {
  66. R += Token[o];
  67. }
  68. for (std::size_t i = 0; i < (R.size() % 4); i++) {
  69. R += Pad;
  70. }
  71.  
  72. return R;
  73. }
  74.  
  75. DType Enc4Char3(const char& A, const char& B, const char& C, const char& D) {
  76. std::int16_t E = (A != '=') ? Token.find(A, 0) : -1;
  77. std::int16_t F = (B != '=') ? Token.find(B, 0) : -1;
  78. std::int16_t G = (C != '=') ? Token.find(C, 0) : -1;
  79. std::int16_t H = (D != '=') ? Token.find(D, 0) : -1;
  80.  
  81. std::uint8_t V=0;
  82. DType DT;
  83.  
  84. if (E >= 0) {
  85. if (F >= 0) {
  86. V = (E & 0x3f) << 2 | (F & 0x3f) >> 4;
  87. DT.push_back(V);
  88. }
  89. else {
  90. V = (E & 0x3f) << 2;
  91. DT.push_back(V);
  92. return DT;
  93. }
  94. }
  95. if (F >= 0) {
  96. if (G >= 0) {
  97. V = (F & 0x3f) << 4 | (G & 0x3f) >> 2;
  98. DT.push_back(V);
  99. }
  100. else {
  101. V = (F & 0x3f) << 4;
  102. DT.push_back(V);
  103. return DT;
  104. }
  105. }
  106. if (G >= 0) {
  107. if (H >= 0) {
  108. V = (G & 0x3f) << 6 | (H & 0x3f);
  109. DT.push_back(V);
  110. }
  111. else {
  112. V =(G & 0x3f) << 6 ;
  113. DT.push_back(V);
  114. return DT;
  115. }
  116. }
  117.  
  118. return DT;
  119.  
  120. }
  121.  
  122. std::string Base64Dec(const std::string& S) {
  123.  
  124. DType D;
  125. std::string R;
  126. for (std::size_t i = 0; i < S.size(); i += 4) {
  127. D = Enc4Char3(S[i], S[i + 1], S[i + 2], S[i + 3]);//エンコード文字列が4字組みになってることを信じている。サクッと死ぬ。
  128. R.insert(R.begin() + R.size(), D.begin(), D.end());
  129. }
  130.  
  131. return R;
  132.  
  133. }
  134.  
  135. int main()
  136. {
  137. std::string S;
  138. std::string R;
  139.  
  140. S = "ABCDEFG";
  141. R = Base64Enc(S);
  142. std::cout << R << std::endl;
  143. R = Base64Dec(R);
  144. std::cout << R << std::endl;
  145. return 0;
  146. }
  147.  
  148.  
Success #stdin #stdout 0s 16072KB
stdin
Standard input is empty
stdout
QUJDREVGRw==
ABCDEFG