fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. #define BASE64BIT 6
  6.  
  7. /* pre-fetch, pre-masking-set */
  8. /* ビットスライシング用クラス */
  9.  
  10. class bitcut {
  11. private:
  12. std::string buffer;
  13. std::string::const_iterator p;;
  14. uint_least8_t mask;
  15. uint_least8_t fetch_byte;
  16. int width;
  17.  
  18. public:
  19. bool isEOL; /* 外部呼び出し側では、このフラグを見てスライスするかどうかを判断する */
  20.  
  21. bitcut(std::string input, int width) { /*コンストラクタにスライスする文字列と、文字列を構成するバイトの有効ビット幅を設定 */
  22. this->buffer = input;
  23. this->p = buffer.begin();
  24. this->width = width;
  25.  
  26. if (p == buffer.end()) {
  27. isEOL = true;
  28. } else {
  29. isEOL = false;
  30. fetch_byte = *p;
  31. mask = 1 << (this->width - 1);
  32. }
  33. }
  34.  
  35. /* bit 数分スライス、tailignore = bit 数分スライスしようとして、残りビットが bit に足りないとき無視するのなら true */
  36. int_least8_t cut(int bit, bool tailignore) { /* bit <= 16 */
  37. uint_least8_t buff = 0;
  38. for (int i = 0; i < bit; i++) {
  39. if (isEOL == false) {
  40. int t = fetch_byte & mask;
  41. buff = buff | ((t > 0) ? 1 : 0);
  42. buff = buff << 1;
  43. mask = mask >> 1;
  44. if (mask == 0) {
  45. this->p++;
  46. if (this->p == buffer.end()) {
  47. this->isEOL = true;
  48. } else {
  49. fetch_byte = *p;
  50. mask = 1 << (this->width - 1);
  51. }
  52. }
  53. } else { /* isEOL == true */
  54. if (tailignore != true)
  55. buff = buff << 1;
  56. }
  57. }
  58. buff = buff >> 1;
  59. return buff;
  60. }
  61. };
  62.  
  63. /* エンコード */
  64. std::string encode(std::string key) {
  65. std::string ret;
  66.  
  67. bitcut bc(key, 8);
  68. if (bc.isEOL == true)
  69. return ret;
  70.  
  71. int_least8_t c;
  72. do {
  73. for (int i = 0 ; i < 4; i++) {
  74. if (bc.isEOL == true) {
  75. c = '=';
  76. } else {
  77. c = bc.cut(BASE64BIT, false);
  78. if (c <= 25) c += 'A';
  79. else if (c <= 51) c = c - 26 + 'a';
  80. else if (c <= 61) c = c - 52 + '0';
  81. else if (c == 62) c = '+';
  82. else if (c == 63) c = '/';
  83. }
  84. ret.push_back(c);
  85. }
  86. } while (bc.isEOL == false);
  87. return ret;
  88. }
  89.  
  90. /* デコード */
  91. std::string decode(std::string key) {
  92. std::string ret;
  93.  
  94. for (std::string::iterator p = key.begin(); p != key.end(); ) {
  95. if (*p == '=') {
  96. p = key.erase(p);
  97. continue;
  98. } else if (*p == '+') {
  99. *p = 62;
  100. p++;
  101. } else if (*p == '/') {
  102. *p = 63;
  103. p++;
  104. } else if (*p <= '9') {
  105. *p = *p - '0' + 52;
  106. p++;
  107. } else if (*p <= 'Z') {
  108. *p = *p - 'A';
  109. p++;
  110. } else if (*p <= 'z') {
  111. *p = *p - 'a' + 26;
  112. p++;
  113. }
  114. }
  115.  
  116. bitcut bc(key, BASE64BIT);
  117. if (bc.isEOL == true)
  118. return ret;
  119. int_least8_t c2;
  120. do {
  121. c2 = bc.cut(8, true);
  122. ret.push_back(c2);
  123. } while (bc.isEOL == false);
  124. return ret;
  125. }
  126.  
  127. void f(std::string key) {
  128. std::string out;
  129. std::cout << "input: " << key << std::endl;
  130. std::cout << "encode: " << (out = encode(key)) << std::endl;
  131. std::cout << "decode: " << decode(out) << std::endl;
  132. }
  133.  
  134. int main() {
  135. // f("ghi");
  136. f("ABCDEFG");
  137. f("Hello, World!");
  138. f("0123456789\"#$%&\'()`=@");
  139. f("12ab34cd56ef78");
  140. return 0;
  141. }
  142. /* end */
Success #stdin #stdout 0s 15248KB
stdin
Standard input is empty
stdout
input:  ABCDEFG
encode: QUJDREVGRw==
decode: ABCDEFG
input:  Hello, World!
encode: SGVsbG8sIFdvcmxkIQ==
decode: Hello, World!
input:  0123456789"#$%&'()`=@
encode: MDEyMzQ1Njc4OSIjJCUmJygpYD1A
decode: 0123456789"#$%&'()`=@
input:  12ab34cd56ef78
encode: MTJhYjM0Y2Q1NmVmNzg=
decode: 12ab34cd56ef78