fork download
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. #define MAX_STR 1000
  6. #define NUM_LETRAS 26
  7.  
  8. int main() {
  9.  
  10. int i, j;
  11.  
  12. char alfabeto[] = "abcdefghijklmnopqrstuvwxyz";
  13. char ordem[] = "aeosrdnitmulcvpgqbfhjxzkyw";
  14. char trocas[] = "jgmfri";
  15. char chave[NUM_LETRAS + 1]; // + 1 por causa do terminador da string.
  16. int frequencias[NUM_LETRAS];
  17. int frequencias2[NUM_LETRAS];
  18. char codificado[MAX_STR];
  19. char decodificado[MAX_STR];
  20.  
  21. // Passo 1:
  22. // Limpa o vetor "frequencias".
  23. for (i = 0; i < NUM_LETRAS; i++) {
  24. frequencias[i] = 0;
  25. }
  26.  
  27. // Passo 2:
  28. // Lê a string codificada do usuário.
  29. printf("Digite o texto criptografado: ");
  30. fgets(codificado, MAX_STR, stdin);
  31.  
  32. // Passo 3:
  33. // Percorre a string "codificado" e conta quantas vezes cada letra aparece,
  34. // guardando a contagem no vetor "frequencias".
  35. for (i = 0; codificado[i]; i++) {
  36. if (codificado[i] >= 'a' && codificado[i] <= 'z') { // Se for letra minúscula.
  37. frequencias[codificado[i] - 'a']++;
  38. } else if (codificado[i] >= 'A' && codificado[i] <= 'Z') { // Se for letra maiúscula.
  39. frequencias[codificado[i] - 'A']++;
  40. }
  41. // Poderia ter um else para os casos onde não é nenhum dos dois,
  42. // mas quando isso acontece, não precisamos fazer nada.
  43. }
  44.  
  45. // Passo 4 (opcional):
  46. // Mostra o vetor "frequencias".
  47. // Aproveita para copiar "frequencias" para "frequencias2".
  48. printf("\n\nTabela de frequências:");
  49. for (i = 0; i < NUM_LETRAS; i++) {
  50. printf(" %c=%d", i + 'a', frequencias[i]);
  51. frequencias2[i] = frequencias[i];
  52. }
  53. printf("\n");
  54.  
  55. // Passo 5:
  56. // Percorre a tabela "frequencias" para montar a "chave", utilizando a ordem das letras
  57. // dada pelo vetor "ordem". Entretanto, o vetor "frequencias" acaba sendo destruído
  58. // por esse processo, e é por isso que temos uma cópia em "frequencias2".
  59. for (i = 0; i < NUM_LETRAS; i++) {
  60. int maior = -1;
  61. int maior_indice = 0;
  62. for (j = 0; j < NUM_LETRAS; j++) {
  63. if (frequencias[j] >= maior) {
  64. maior = frequencias[j];
  65. maior_indice = j;
  66. }
  67. }
  68. chave[maior_indice] = ordem[i];
  69. frequencias[maior_indice] = -1;
  70. }
  71. chave[NUM_LETRAS] = 0;
  72.  
  73. // Passo 6 (opcional):
  74. // Percorre a tabela "frequencias2" para procurar por letras que ocorram um mesmo
  75. // número de vezes (que não seja zero) e mostrar isso ao usuário.
  76. // Entretanto, "frequencias2" acaba sendo destruído nesse processo.
  77. for (i = 0; i < NUM_LETRAS; i++) {
  78. if (frequencias2[i] == 0) continue;
  79. int p = 0;
  80. for (j = i + 1; j < NUM_LETRAS; j++) {
  81. if (frequencias2[j] != frequencias2[i]) continue;
  82. if (p == 0) {
  83. printf("Frequências iguais [%d]: %c", frequencias2[i], i + 'a');
  84. p = 1;
  85. }
  86. printf("%c", (j + 'a'));
  87. frequencias2[j] = 0;
  88. }
  89. frequencias2[i] = 0;
  90. if (p != 0) printf("\n");
  91. }
  92.  
  93. // Passo 7 (opcional):
  94. // Troca algumas letras da "chave" a fim de ajeitar manualmente os casos que estiverem errados.
  95. // As letras das posições pares são permutadas com as das posições ímpares de "trocas".
  96. for (i = 0; trocas[i]; i += 2) {
  97. char temp = chave[trocas[i] - 'a'];
  98. chave[trocas[i] - 'a'] = chave[trocas[i + 1] - 'a'];
  99. chave[trocas[i + 1] - 'a'] = temp;
  100. }
  101.  
  102. // Passo 8 (opcional):
  103. // Mostra a chave.
  104. printf("\nA chave é:\n%s\n%s\n", alfabeto, chave);
  105.  
  106. // Passo 9:
  107. // Tendo o vetor "chave" montado, usa ele para formar a string "decodificado"
  108. // a partir de "codificado".
  109. for (i = 0; codificado[i]; i++) {
  110. if (codificado[i] >= 'a' && codificado[i] <= 'z') { // Letras minúsculas.
  111. decodificado[i] = chave[codificado[i] - 'a'];
  112. } else if (codificado[i] >= 'A' && codificado[i] <= 'Z') { // Letras maiúsculas.
  113. decodificado[i] = chave[codificado[i] - 'A'] - 'a' + 'A';
  114. } else { // Copia qualquer outra coisa diretamente.
  115. decodificado[i] = codificado[i];
  116. }
  117. }
  118. decodificado[i] = codificado[i]; // Copia o terminador nulo.
  119.  
  120. // Passo 10:
  121. // Mostra o texto "decodificado".
  122. printf("\nO texto descriptografado é:\n%s\n", decodificado);
  123. }
Success #stdin #stdout 0s 4532KB
stdin
Cscmxcszfsocmfzscssjncwcgfspezgcfkjgznvcwbmcjcwesjvcncbfmxcmzsnenkcgzcnvzsncazicgfsbcsscmcxcjngccwzxgcvcbmfocnczxbzmjifsziezmmcszsrfmkcgfsxcjsgfpezbmfxzvjccrfmkchexcnczznvm
stdout
Digite o texto criptografado: 

Tabela de frequências: a=1 b=6 c=36 d=0 e=6 f=13 g=9 h=1 i=3 j=8 k=4 l=0 m=14 n=11 o=2 p=2 q=0 r=2 s=18 t=0 u=0 v=6 w=4 x=8 y=0 z=18
Frequências iguais [1]: ah
Frequências iguais [6]: bev
Frequências iguais [8]: jx
Frequências iguais [4]: kw
Frequências iguais [2]: opr
Frequências iguais [18]: sz

A chave é:
abcdefghijklmnopqrstuvwxyz
hlawustfgnvyrdbqkpozxmcije

O texto descriptografado é:
Aoariaoesobarseoaoondacatsoquetasvntedmaclranacuonmadalsriareodudvateadmeodahegatsolaooaraiandtaaceitamalrsbadaeilerngsoeguerraoeopsrvatsoianotsquelrsiemnaapsrvafuiadaeedmr