2017-10-01 7 views
-1

J'essaie de créer un code qui utilisera l'intégralité du jeu de caractères ASCII imprimable. Mon problème est que quand il s'agit de caractères qui seront un nombre supérieur à 126, ils s'impriment en '?', À l'exception de 'r', qui s'imprime correctement. Pourquoi mon code permet-il à 'r' de revenir à un caractère imprimable mais pas à des caractères après cela? (Stuvwxyz {|} ~)ROT-13 utilisant l'ensemble des caractères ASCII imprimables C++

"S'il vous plaît entrer votre mot de passe

abcdefghijklmnopqrstuvwxyz. {|} ~

de nopqrstuvwxyz {|}! ~ ????????????"

#include <iostream> 
#include <string> 
using namespace std; 

void encrypt(string password) 
{ 

int count = 0; 
char i; 

    for (count = 0; count < password.length(); count++) 
    { 
     i = password.at(count) + 13; 
      if (i >= 127) 
       { 
        i = 32 + (i - 126); 
        cout << i; 
       } 
      else 
       cout << i;   
    } 
    return; 
} 

int main() 
{ 
    string password; 

    cout << "Please enter your password." << endl; 
    cin >> password; 

    encrypt(password); 
    cout << "\n"; 
    return 0; 
} 
+2

"Mon problème est que quand il s'agit de caractères qui sera un nombre supérieur à 126, ils impriment comme ' ? ', "- car ces nombres ne font pas partie du jeu de caractères ASCII. –

+0

BTW, si vous utilisiez ** le débogueur **, vous auriez vu la valeur dans 'i' est' -128' pour '" s "', pas '+ 128'. ... la prochaine fois, avant de poster sur SO, essayez d'abord de déboguer. – Ped7g

Répondre

0

Votre plate-forme cible a signé char, les valeurs si valides dans char sont de portée -128 .. +127.

Ainsi votre if (i >= 127) ne couvrira que 'r' (valeur 114), pour la 's'i est égal à -128, et non +128. Et votre if sera false et vous obtiendrez une valeur de -128 caractères.

Une solution rapide est de déclarer i comme unsigned char pour fonctionner plutôt sur la plage +0 .. +255. Si vous ne voulez prendre en charge qu'une entrée ASCII 7b valide, cela suffit pour que tout ce +13 arithmétique soit correct.

Aussi je ne sais pas pourquoi vous faites 32 + (i - 126);, c'est de demander r de se convertir à ! (33), en sautant l'espace (32), qui est le caractère ASCII imprimable.

Ainsi, après les corrections appliquées et en simplifiant un peu le code (vers C++ de style), j'ai fini avec:

void encrypt(const string & password) 
{ 
    for (unsigned char charToRot13 : password) { 
     charToRot13 += 13; 
     if (127 <= charToRot13) charToRot13 -= (127 - ' '); 
     cout << charToRot13; 
    } 
} 

qui fait entrée + sortie ('r' maps maintenant ' '):

Please enter your password. 
abcopqrstuvw 
nop|}~ !"#$% 

MAIS. La caractéristique principale de ROT13 est, que vous pouvez crypter et déchiffrer le texte par la même opération. C'est à dire. "abc" -> "nop" -> "abc" -> "nop" -> ...

Votre conversion à toute la gamme ASCII rompt cette fonctionnalité. Donc, ce que vous voulez probablement est de couvrir +32 .. +126 gamme de valeurs ASCII, c'est 95 d'entre eux. 95/2 = 47,5, pas bon. Supprimons l'espace, car vous l'avez déjà fait par -126, donc vous ne le voulez probablement pas. La plage de valeurs à chiffrer est alors +33 .. +126 = 94 d'entre eux. 94/2 = 47, bien. Pour obtenir un cryptage de type ROT13 pour toute la plage ASCII (à l'exception de l'espace), vous pouvez utiliser ROT47.

void encrypt(const string & password) 
{ 
    for (unsigned char charToRot47 : password) { 
     if (charToRot47 < 33 || 126 < charToRot47) { 
      cout << "\nERROR: detected invalid character.\n"; 
      break; 
     } 
     charToRot47 += 47; 
     if (126 < charToRot47) charToRot47 -= 94; 
     cout << charToRot47; 
    } 
} 

Affichera:

Please enter your password. 
xyz{|}~!"#$%000000IJKLMNOPQRST 
IJKLMNOPQRST______xyz{|}~!"#$% 

(remarquez comment par exemple 'y' -> 'J' -> 'y' -> 'J' -> ...)

+0

Et j'ai nettoyé ce code final pour fonctionner uniquement avec les "constantes magiques" de la description du texte, c'est à dire la plage valide est 33..126, le nombre de caractères couverts est 94, et 94/2 = 47. Il n'y a pas de bonne raison soudainement utiliser des nombres magiques comme 127 et similaires, ceux-ci ne sont pas directement liés à ROT47, et en effet il est possible de l'écrire proprement avec seulement les valeurs de la définition ROT47. – Ped7g