fork download
  1. //
  2. // main.cpp
  3. // Toy Tetragraph Hash
  4. //
  5. // Created by Brian Schack on 2/19/13.
  6. // Copyright (c) 2013 Brian Schack. All rights reserved.
  7. //
  8.  
  9. #include <assert.h>
  10. #include <iostream>
  11. #include <vector>
  12. using namespace std;
  13.  
  14. string toyTetragraphHash(string message) {
  15. // First, tth divides the message into blocks of 16 letters, ignoring spaces, punctuation, and capitalization
  16. int characterIndex = 0;
  17. vector<string> blocksOfCharacters;
  18. string blockOfCharacters = "";
  19. blocksOfCharacters.push_back(blockOfCharacters);
  20. while (true) {
  21. if (characterIndex >= message.size()) {
  22. break;
  23. }
  24. char character = message.at(characterIndex);
  25. if ((character >= 'A' && character <= 'Z') || (character >= 'a' && character <= 'z')) {
  26. if (blocksOfCharacters.at(blocksOfCharacters.size() - 1).size() >= 16) {
  27. blocksOfCharacters.push_back(blockOfCharacters);
  28. }
  29. if (character >= 'A' && character <= 'Z') {
  30. character += 32;
  31. }
  32. blocksOfCharacters.at(blocksOfCharacters.size() - 1) += character;
  33. }
  34. characterIndex++;
  35. }
  36.  
  37. // If the message length is not divisible by 16, it is padded out with nulls
  38. while (true) {
  39. if (blocksOfCharacters.at(blocksOfCharacters.size() - 1).size() < 16) {
  40. blocksOfCharacters.at(blocksOfCharacters.size() - 1) += 'a';
  41. } else {
  42. break;
  43. }
  44. }
  45.  
  46. // blocksOfCharacters
  47. int blockIndex = 0;
  48. while (true) {
  49. // cout << blocksOfCharacters.at(blockIndex) << '\n';
  50. blockIndex++;
  51. if (blockIndex >= blocksOfCharacters.size()) {
  52. break;
  53. }
  54. }
  55.  
  56. // A four-number running total is maintained that starts out with the value (0, 0, 0, 0)
  57. vector<int> totals(4);
  58.  
  59. // totals
  60. int totalIndex = 0;
  61. while (true) {
  62. // cout << totals.at(totalIndex) << ' ';
  63. totalIndex++;
  64. if (totalIndex >= 4) {
  65. // cout << '\n';
  66. break;
  67. }
  68. }
  69.  
  70. // Get the next block of text and arrange it as a row-wise 4 x 4 block of text and covert it to numbers (A = 0, B = 1, ...)
  71. vector<vector<int>> blocksOfNumbers;
  72. vector<int> blockOfNumbers;
  73. blocksOfNumbers.push_back(blockOfNumbers);
  74. while (true) {
  75. blockOfCharacters = blocksOfCharacters.at(blocksOfNumbers.size() - 1);
  76. char character = blockOfCharacters.at(blocksOfNumbers.at(blocksOfNumbers.size() - 1).size());
  77. blocksOfNumbers.at(blocksOfNumbers.size() - 1).push_back(character - 97);
  78. if (blocksOfNumbers.at(blocksOfNumbers.size() - 1).size() >= 16) {
  79. if (blocksOfNumbers.size() < blocksOfCharacters.size()) {
  80. blocksOfNumbers.push_back(blockOfNumbers);
  81. } else {
  82. break;
  83. }
  84. }
  85. }
  86.  
  87. // blocksOfNumbers
  88. blockIndex = 0;
  89. int numberIndex = 0;
  90. while (true) {
  91. // cout << blocksOfNumbers.at(blockIndex).at(numberIndex) << ' ';
  92. numberIndex++;
  93. if (numberIndex >= 16) {
  94. // cout << '\n';
  95. blockIndex++;
  96. numberIndex = 0;
  97. if (blockIndex >= blocksOfNumbers.size()) {
  98. break;
  99. }
  100. }
  101. }
  102.  
  103. // Then add each column mod 26 and add the result to the running total mod 26
  104. blockIndex = 0;
  105. int columnIndex = 0;
  106. while (true) {
  107. blockOfNumbers = blocksOfNumbers.at(blockIndex);
  108. totals.at(columnIndex) += blockOfNumbers.at(columnIndex) + blockOfNumbers.at(columnIndex + 4) + blockOfNumbers.at(columnIndex + 8) + blockOfNumbers.at(columnIndex + 12);
  109. totals.at(columnIndex) = totals.at(columnIndex) % 26;
  110. columnIndex++;
  111. if (columnIndex >= 4) {
  112. blockIndex++;
  113. columnIndex = 0;
  114. if (blockIndex >= blocksOfNumbers.size()) {
  115. break;
  116. }
  117. }
  118. }
  119.  
  120. // totals
  121. totalIndex = 0;
  122. while (true) {
  123. // cout << totals.at(totalIndex) << ' ';
  124. totalIndex++;
  125. if (totalIndex >= 4) {
  126. // cout << '\n';
  127. break;
  128. }
  129. }
  130.  
  131. // Using the matrix from round 1, rotate the first row left by 1, second row left by 2, third row left by 3, and reverse the order of the fourth row
  132. vector<vector<int>> rotatedBlocks;
  133. vector<int> rotatedBlock;
  134. rotatedBlocks.push_back(rotatedBlock);
  135. while (true) {
  136. blockOfNumbers = blocksOfNumbers.at(rotatedBlocks.size() - 1);
  137. vector<int> rotations {1, 2, 3, 0, 6, 7, 4, 5, 11, 8, 9, 10, 15, 14, 13, 12};
  138. int rotation = rotations.at(rotatedBlocks.at(rotatedBlocks.size() - 1).size());
  139. rotatedBlocks.at(rotatedBlocks.size() - 1).push_back(blockOfNumbers.at(rotation));
  140. if (rotatedBlocks.at(rotatedBlocks.size() - 1).size() >= blockOfNumbers.size()) {
  141. if (rotatedBlocks.size() < blocksOfNumbers.size()) {
  142. rotatedBlocks.push_back(rotatedBlock);
  143. } else {
  144. break;
  145. }
  146. }
  147. }
  148.  
  149. // rotatedBlocks
  150. blockIndex = 0;
  151. numberIndex = 0;
  152. while (true) {
  153. // cout << rotatedBlocks.at(blockIndex).at(numberIndex) << ' ';
  154. numberIndex++;
  155. if (numberIndex >= 16) {
  156. // cout << '\n';
  157. blockIndex++;
  158. numberIndex = 0;
  159. if (blockIndex >= rotatedBlocks.size()) {
  160. break;
  161. }
  162. }
  163. }
  164.  
  165. // Now add each column mod 26 and add the result to the running total
  166. blockIndex = 0;
  167. columnIndex = 0;
  168. while (true) {
  169. rotatedBlock = rotatedBlocks.at(blockIndex);
  170. totals.at(columnIndex) += rotatedBlock.at(columnIndex) + rotatedBlock.at(columnIndex + 4) + rotatedBlock.at(columnIndex + 8) + rotatedBlock.at(columnIndex + 12);
  171. totals.at(columnIndex) = totals.at(columnIndex) % 26;
  172. columnIndex++;
  173. if (columnIndex >= 4) {
  174. blockIndex++;
  175. columnIndex = 0;
  176. if (blockIndex >= rotatedBlocks.size()) {
  177. break;
  178. }
  179. }
  180. }
  181.  
  182. // totals
  183. totalIndex = 0;
  184. while (true) {
  185. // cout << totals.at(totalIndex) << ' ';
  186. totalIndex++;
  187. if (totalIndex >= 4) {
  188. // cout << '\n';
  189. break;
  190. }
  191. }
  192.  
  193. // After the final block is processed, convert the final running total to letters.
  194. string hash = "";
  195. totalIndex = 0;
  196. while (true) {
  197. hash += totals.at(totalIndex) + 97;
  198. totalIndex++;
  199. if (totalIndex >= 4) {
  200. break;
  201. }
  202. }
  203.  
  204. return hash;
  205. }
  206.  
  207. int main(int argc, const char* argv[]) {
  208. // This problem introduces a hash function similar in spirit to SHA that operates on letters instead of binary data. It is called the toy tetragraph hash (tth).
  209. cout << "Toy Tetragraph Hash\n";
  210. cout << "Brian Schack\n";
  211.  
  212. assert(toyTetragraphHash("ABCDEFGHIJKLMNOP") == "fhjl");
  213. assert(toyTetragraphHash("I leave twenty million dollars to my friendly cousin Bill.") == "bfqg");
  214. assert(toyTetragraphHash("AYHGD") == "bfqg");
  215.  
  216. // Given a message consisting of a sequence of letters, tth produces a hash value consisting of four letters.
  217. cout << "Message? ";
  218. string message;
  219. getline(cin, message);
  220. cout << toyTetragraphHash(message);
  221.  
  222. return 0;
  223. }
Success #stdin #stdout 0.01s 5280KB
stdin
I leave twenty million dollars to my friendly cousin Bill
stdout
Toy Tetragraph Hash
Brian Schack
Message? bfqg