[Objective-C] Substitution Caesar et Vigenère

NSProblemeNSProbleme Membre
décembre 2016 modifié dans Objective-C, Swift, C, C++ #1

Bonjour,


 


J'ai deux méthode Caesar et Vigenère qui me permettent de crypter ou decrypter un message en utilisant une clès.


 


Pour la méthode Caesar ca fonctionnement parfaitement, mais pour vigenère je ne comprends pas ce qui se passe car quand je fais un NSLog le résultat ne s'affiche pas forcement.


 


(Petit rappel


Caesar : j'entre un message et un chiffre puis j'obtiens un nouveau message avec les lettres décalés en fonction du chiffre.


Pour vigenère c'est pareil mais là  la clef est un mot de même longueur que le message et j'obtiens un nouveau avec les lettres décalés en fonction de la valeur des lettres qui compose la clef)


 


(Boolean action : c'est quand j'appuie sur le bouton crypter renvoie true et inversement)



+(NSString*)Cesar:(NSString*)msg :(NSString*)cles :(Boolean)action
{
int intCles = [cles intValue];

if (!action){intCles = intCles*-1;}

NSString* sortie = @"";
int v = 0;

NSLog(@%@ IIII %i",msg,intCles);

for(int i ; i < msg.length ; i++)
{
int c = [msg characterAtIndex:i];
NSLog(@%c --- %i,c,c);
if((c>=(int)'a') && (c<=(int)'z'))
{
v = (int)'a'+intCles;
if (v<(int)'a'){v = (((c-(int)'z')+intCles)%26)+(int)'z';}
else{v = (((c-(int)'a')+intCles)%26)+(int)'a';}
}

else if((c>=(int)'A') && (c<=(int)'Z'))
{
v = (int)'A'+intCles;
if (v<(int)'A'){v = (((c-(int)'Z')+intCles)%26)+(int)'Z';}
else{v = (((c-(int)'A')+intCles)%26)+(int)'A';}

}

else { v=(char)c;}

sortie = [NSString stringWithFormat:@%@%c",sortie,v] ;

}

NSLog(@<; %@ >",sortie);
return sortie;
}

+(NSString*)Vigenere:(NSString*)msg :(NSString*)cles :(Boolean)action
{
NSString* sortie = @"";
NSString* intCles;
NSString* c ;
for(int i ; i < msg.length ; i++)
{
intCles = [NSString stringWithFormat:@%i,((int)[cles characterAtIndex:i] - (int)'a')+1];
c = [NSString stringWithFormat:@%c,[msg characterAtIndex:i]];
sortie = [NSString stringWithFormat:@%@%@",sortie,[Substitutions Cesar:c :intCles :action]];

}

return sortie;
}


Réponses

  • Joanna CarterJoanna Carter Membre, Modérateur
    C'est pas du tout clair comment tu utilises le code. C'est quoi, le code qui appelle ces méthodes ?


    Je vois que tu es nouveau, merci d'aller te présenter dans la section "Présentation des Membres" pour que l'on sache plus sur ton parcours, ton niveau et ton expérience et que l'on adapte nos réponses en conséquence
  • NSProblemeNSProbleme Membre
    janvier 2017 modifié #3

    Bonjour,


     


    J'ai crée une master-detail application


     


    DetailViewController.m



    // tvD : UITextField pour entrer un message dans le champs décrypté.
    // tvC : UITextField pour entrer un message dans le champs crypté.
    // cles : UITextField pour entrer une cles.
    // méthodeDeCryptage : NSString, c'est la cellule quand on a choisie dans le TableView dans le MasterViewController

    - (IBAction)bCrypter:(id)sender { [self action_Crypter_Decrypter:tvD :tvC :true]; }
    - (IBAction)bDecrypter:(id)sender { [self action_Crypter_Decrypter:tvC :tvD :false]; }

    - (void) action_Crypter_Decrypter:(UITextField*)tv1 :(UITextField*)tv2 :(Boolean)b
    {
    if ([cles.text length] == 0){ [self toast:@Entrée une clès]; }
    else
    {
    if ([methodeDeCryptage isEqualToString:@Caesar]){ tv1.text = [Substitutions Cesar:tv2.text :cles.text :b]; }

    else if ([methodeDeCryptage isEqualToString:@Vigenère])
    {
    if ([cles.text length]!=[tv2.text length]){ [self toast:@Entrée une clès de même taille que votre texte];
    }
    else { tv1.text = [Substitutions Vigenere:tv2.text :cles.text :b]; }
    }
    }

    }

  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #4

    Qui t'a enseigné l'Objective-C ?


     


    Est-ce que t'as appris des autres langues auparavant ?


     


    Pourquoi choisir Objective-C au lieu de Swift ?


     


    À part de ces questions...


     


    Ton code est très mal formé. Il manque les espaces et les lignes d'espace.


     


    Les noms des méthodes ne devraient ni commencer avec une majuscule, ni contenir les tirets bas


     


    Les noms des propriétés, vars et méthodes sont vraiment cryptiques ; il vaut mieux les nommer plus descriptifs.


     


    Tu traites un NSString comme une liste de int (32 bits) ; en fait, c'est une liste de unichar (unsigned short / 16 bits). En plus, en traitant un NSString, il faut considérer que l'on y pourrait trouver les "grapheme clusters" (symboles unicode qui se composent de plus de 1 unichar)


     


    En convertant les chars littéraux ('A', etc) vers les ints, tu ignores qu'ils ne composent que de 8 bits et tu les mets dans un int de 32  bits.


     


    Peut-être ça marche dans ce petit exemple mais, un jour, tu trouveras que ces trucs puissent te mordre  >:D


     


    Le construction if..else dans Cesar est douteux, voir ambigu, sur son chemins d'exécution.


     


    J'ai fait de la ménage sur ton code pour te montrer quelques procédures meilleurs.



    // Substitutions.h

    typedef NS_ENUM(NSInteger, SubstitutionAction)
    {
    Crypter,
    Decrypter
    };


    typedef NS_ENUM(NSInteger, MethodeCryptage)
    {
    Caesar,
    Vigenere
    };


    @interface Substitutions : NSObject

    + (NSString*)substituerEnCaesar:(NSString*)message avecCles:(NSString*)cles action:(SubstitutionAction)action;

    + (NSString*)substituerEnVigenere:(NSString*)message avecCles:(NSString*)cles action:(SubstitutionAction)action;

    @end



    // Substitutions.m

    @implementation Substitutions

    + (NSString*)substituerEnCaesar:(NSString*)message avecCles:(NSString*)cles action:(SubstitutionAction)action;
    {
    int intCles = action == Crypter ? cles.intValue : -cles.intValue;

    NSString* sortie = @"";

    unichar v = 0;

    NSLog(@%@ IIII %i", message, intCles);

    for(int i; i < message.length; i++)
    {
    unichar character = [message characterAtIndex:i];

    NSLog(@%c --- %i, character, character);

    NSCharacterSet *characterSet = [NSCharacterSet lowercaseLetterCharacterSet];

    if([characterSet characterIsMember:character])
    {
    v = 'a' + intCles;

    if (v < 'a')
    {
    v = (((character - 'z') + intCles) % 26) + 'z';
    }
    else
    {
    v = (((character - 'a') + intCles) % 26) + 'a';
    }
    }
    else
    {
    characterSet = [NSCharacterSet uppercaseLetterCharacterSet];

    if([characterSet characterIsMember:character])
    {
    v = 'A' + intCles;

    if (v < 'A')
    {
    v = (((character - 'Z') + intCles) % 26) + 'Z';
    }
    else
    {
    v = (((character - 'A') + intCles) % 26) + 'A';
    }
    }
    else
    {
    v = character;
    }
    }

    sortie = [NSString stringWithFormat:@%@%C", sortie, v] ;
    }

    NSLog(@<; %@ >",sortie);

    return sortie;
    }

    + (NSString*)substituerEnVigenere:(NSString*)message avecCles:(NSString*)cles action:(SubstitutionAction)action;
    {
    NSString* sortie = @"";

    NSString* intCles;

    NSString* c;

    for(int i; i < message.length; i++)
    {
    intCles = [NSString stringWithFormat:@%i,((int)[cles characterAtIndex:i] - (int)'a') + 1];

    c = [NSString stringWithFormat:@%c,[message characterAtIndex:i]];

    sortie = [NSString stringWithFormat:@%@%@", sortie,[Substitutions substituerEnCaesar:c avecCles:intCles action:action]];
    }

    return sortie;
    }



    // ViewController.m

    @interface ViewController ()

    @property (weak, nonatomic) IBOutlet UITextField *champsDecrypte;

    @property (weak, nonatomic) IBOutlet UITextField *champsCrypte;

    @property (weak, nonatomic) IBOutlet UITextField *cles;

    @property MethodeCryptage methodeDeCryptage;

    @end


    @implementation ViewController

    - (IBAction)boutonCrypter:(id)sender
    {
    [self substituerChampsDestination:self.champsDecrypte avecChampsSource:self.champsCrypte :Crypter];
    }

    - (IBAction)boutonDecrypter:(id)sender
    {
    [self substituerChampsDestination:self.champsCrypte avecChampsSource:self.champsDecrypte :Decrypter];
    }

    - (void)substituerChampsDestination:(UITextField *)champsDestination avecChampsSource:(UITextField *)champsSource :(SubstitutionAction)action
    {
    if (self.cles.text.length == 0)
    {
    [self toast:@Entrée une clès];
    }
    else
    {
    if (self.methodeDeCryptage == Caesar)
    {
    champsDestination.text = [Substitutions substituerEnCaesar:champsSource.text avecCles:self.cles.text action:action];
    }
    else if (self.methodeDeCryptage == Vigenere)
    {
    if (self.cles.text.length != champsSource.text.length)
    {
    [self toast:@Entrée une clès de même taille que votre texte];
    }
    else
    {
    champsDestination.text = [Substitutions substituerEnVigenere:champsSource.text avecCles:self.cles.text action:action];
    }
    }
    }
    }

    - (void)toast:(NSString *)str
    {

    }


    Maintenant le code est un peu plus clair mais il manque encore de travaille. Néanmoins, je crois que si tu examinais la méthode substituerEnVigenere:avecCles:action: , tu y trouveras une faute de logique.


  • Ton codage Caesar me parait compliqué, avec des if-else dans tout les sens.

  • DrakenDraken Membre
    janvier 2017 modifié #6

    Voici une fonction Caesar écrite en Swift (Je serais incapable de le coder en objective-C, même si ma vie en dépendait).



    func codageCaesar(message:String, decalage:UInt32) -> String {
    var resultat = String()
    for c in message.unicodeScalars {
    let caesar = c.value + decalage
    if let nouveauCaractere = UnicodeScalar(caesar) {
    resultat.append(String(nouveauCaractere))
    }
    }
    return resultat
    }


    Exemple d'utilisation :



    let texte = "abcd efgh"
    let caesar = codageCaesar(message: texte, decalage: 1)

    print (texte)
    print (caesar)


    Affichage :


     



     


    abcd efgh


    bcde!fghi


     


     


    Tu peux remarquer que l'espace a aussi été transformé en un autre caractère, ce qui améliore l'efficacité du codage. Avec ton système, seules les lettres "a-z" et "A-Z" sont cryptés. Le mien code TOUT, y compris les signes de ponctuation, les minuscules accentués, les espaces et les emojis.


  • Joanna CarterJoanna Carter Membre, Modérateur

    Malheureusement, unicodeScalars n'existe pas sur NSString ; du coup, c'est beaucoup plus difficile de décaler les "characters" d'un NSString en Objective-C  >:(


  • DrakenDraken Membre
    janvier 2017 modifié #8

    Comment cela fonctionne ?


     


    Pour des raisons de compatibilité avec Objective-C, Swift peut utiliser NSString pour stocker des chaines de caractères, mais il possède aussi son propre type, plus souple : String.


     


    String possède des fonctions d'énumération, ce qui permet de lire les caractères d'une manière simple, sans passer par une boucle classique.


    a



    let texte = "abcd"
    for c in texte.characters {
    print (c)
    }

    a


    C'est plus propre et plus lisible que la boucle habituelle. Affichage :


    a



     


    a


    b


    c


    d


     


    a


    On peut aussi énumérer le texte de manière à  récupérer directement des caractères Unicode. C'est une approche plus moderne.


    a



    let texte = "abcd"
    for u in texte.unicodeScalars {
    print (u)
    print (u.value)
    }


    a


    L'opérateur .value permet d'obtenir la valeur numérique d'un caractère Unicode. Affichage :


    a


     



     


    a


    97


    b


    98


    c


    99


    d


    100


     


    a


    La représentation numérique d'un Unicode est un UInt32 (entier 32 bits non signé). C'est beaucoup plus long que les 8 bits de l'ASCII, mais cela permet de stocker les millions de caractères Unicodes possibles dans un seul chiffre (caractères français, russes, japonais, chinois, grecs, hindous, emojis, etc..).


     


    Une simple addition donne le code Caesar.


    a



    let caesar = c.value + decalage

    a


    La fonction UnicodeScalar permet de convertir un entier 32 bits non signé en caractère Unicode. Il y a une petite subtilité dans le code. Théoriquement, cela devrais s'écrire comme :


    a



    let nouveauCaractere = UnicodeScalar(caesar)

    a


    Ce n'est pas le cas à  cause des mécanismes de sécurité intégré de Swift. Il est possible que la conversion d'un entier vers un Unicode échoue, à  cause d'une valeur erronée. C'est le genre de bug qui peut planter un programme classique.


     


    En Swift on écrit :


    a



    let caesar = c.value + decalage
    if let nouveauCaractere = UnicodeScalar(caesar) {
    resultat.append(String(nouveauCaractere))
    }


    a


    Cela veut dire "on essaye de réaliser l'opération nouveauCaractere = UnicodeScalar(caesar)". Si c'est bon, on exécute les instructions entre accolades, sinon on ne fait rien. On peut même afficher un avertissement pour signaler un problème.


    a



    let caesar = c.value + decalage
    if let nouveauCaractere = UnicodeScalar(caesar) {
    resultat.append(String(nouveauCaractere))
    } else {
    print ("Attention, la conversion Unicode a échouée !!")
    }


    a


    J'utilise une String vide pour stocker le résultat du codage Caesar.


    a



    var resultat = String()

    a


    L'opérateur append() permet d'ajouter du contenu à  une String. Mais il ne sait pas comment ajouter un Unicode à  une String, alors j'ai besoin de convertir l'Unicode en une nouvelle chaà®ne de caractère. 


    a



    resultat.append(String(nouveauCaractere)) 

    a


    Et voilà , c'est (presque) simple. J'espère t'avoir convaincu que Swift c'est le Bien pour un novice ..


  • DrakenDraken Membre
    janvier 2017 modifié #9


    Malheureusement, unicodeScalars n'existe pas sur NSString ; du coup, c'est beaucoup plus difficile de décaler les "characters" d'un NSString en Objective-C  >:(




    a


    OBJECTIVE-C C'EST LE MAL !!!   >:D  >:)


  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #10

    Bah non ! Dans ce cas, ce n'est pas Objective-C qui est mal mais sûrement NSString  ::)  >:D




  • [Bah [non]] ! [Dans ce cas, [ce n'est pas [Objective-C[]] qui est mal] [mais sûrement NSString  ::)]&nbsp;[&nbsp; &gt;:D]



  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #12

    Grâce à  ton exemple, j'ai réussi (d'une façon). Ce n'est pas avec les unicode scalars mais les unichar, qui me semble suffisant pour l'exemple donné.



    + (NSString*)substituerEnCaesar:(NSString*)message decalage:(unsigned short)decalage action:(SubstitutionAction)action
    {
    NSMutableString *resultat = [NSMutableString string];

    for (NSUInteger i = 0 ; i < message.length ; i++)
    {
    unichar character = [message characterAtIndex:i];

    unichar modifiedCharacter = character + (action == Crypter ? decalage : -decalage);

    [resultat appendString:[NSString stringWithCharacters:&modifiedCharacter length:1]];
    }

    return resultat;
    }

    + (NSString*)substituerEnVigenere:(NSString*)message avecCles:(NSString*)cles action:(SubstitutionAction)action;
    {
    NSString* sortie = @"";

    NSString* intCles;

    NSString* character;

    for(int i = 0; i < message.length; i++)
    {
    intCles = [NSString stringWithFormat:@%i,([cles characterAtIndex:i] - 'a')];

    character = [NSString stringWithFormat:@%C,[message characterAtIndex:i]];

    sortie = [sortie stringByAppendingString:[Substitutions substituerEnCaesar:character decalage:intCles.intValue action:action]];
    }

    return sortie;
    }

  • Joanna CarterJoanna Carter Membre, Modérateur

    Draken - tu te rends compte que nous avons fait les devoirs de vacances pour NSProbleme ?  ::)


  • C'est pas grave, si cela le persuade de l'infini supériorité du Swift ..  ::)

  • DrakenDraken Membre
    janvier 2017 modifié #15

    En y réfléchissant, il y a un problème potentiel dans ton code, Joanna. Tu fais le calcul sans vérifier si le résultat est un caractère Unicode valide. Il doit y avoir des "trous" dans la liste des UniCodes, surtout avec les caractères complexes composés de plusieurs informations.


     


    Le cryptage d'un caractère étendu, comme un symbole chinois ou un émoji pourrais créer un caractère non valide, avec des résultats imprévisibles (erreur d'affichage, plantage, etc..). Dans le meilleur des cas, le "bad caractère" ne seras pas affiché, altérant le message.


     


    Cela ne peut pas arriver dans mon exemple en Swift, UnicodeScalar() vérifiant la validité de la conversion.


    g



    let caesar = c.value + decalage
    if let nouveauCaractere = UnicodeScalar(caesar) {
    resultat.append(String(nouveauCaractere))
    } else {
    print ("Attention, la conversion Unicode a échouée !!")
    }

    a


    Je n'y ai pas pensé en écrivant le code. C'est Swift qui m'a forcé à  utiliser un "if let", preuve qu'il est plus malin que moi. Ou plutôt que les ingénieurs d'Apple ont bien fait leurs travail en concevant les bibliothèques d'objets Swift.


     

    a

  • Joanna CarterJoanna Carter Membre, Modérateur
    T'as raison mais, en limitant les characters à  unichar, et avec la condition préalable de l'exercice présumée de n'utiliser que les lettres de l'alphabet romain, ça ira ;)
  • DrakenDraken Membre
    janvier 2017 modifié #17

    C'est clair !


    Mais c'est toujours utile pour un débutant en programmation de savoir qu'un code simple, ayant l'air de fonctionner, puisse présenter des failles dans certaines situations.


  • Joanna CarterJoanna Carter Membre, Modérateur
    Tout à  fait !
  • NSProblemeNSProbleme Membre
    janvier 2017 modifié #19

    Bonjour,


     


    Pour revenir au début ^^, j'ai fait les modifications. Pour la méthode Cesar et j'ai un petit problème j'ai rien en sortie et j'ai voulu voir ce qui se passe avec un NSLog mais le NSLog qui dans la boucle for n'affiche rien.


     


    En fait j'ai utilisé le modulo et le reste pour qu'on puisse entrer n'importe quelle valeur positif ou négatif pour la clef.


    Si je veux crypter "a" avec la clef "-1" , j'obtiendrais "z",


    pour crypter "a" avec la clef "27", j'obtiendrai "b".



    +(NSString*)Cesar:(NSString*)msg :(NSString*)cles :(SubstitutionAction)action
    {
    // unsigned short decalage = cles.intValue;
    // NSMutableString *resultat = [NSMutableString string];
    //
    // for (NSUInteger i = 0 ; i < message.length ; i++)
    // {
    // unichar character = [message characterAtIndex:i];
    // unichar modifiedCharacter = character + (action == Crypter ? decalage : -decalage);
    // NSLog(@%c,modifiedCharacter);
    // [resultat appendString:[NSString stringWithCharacters:&modifiedCharacter length:1]];
    // }
    // return resultat;


    unsigned short intCles = action == Crypter ? cles.intValue : -cles.intValue ;

    NSString* sortie = @"";
    unichar v = 0;

    NSLog(@%lu +++ %@",(unsigned long)msg.length,msg);
    for(int i ; i < msg.length ; i++)
    {
    unichar caractere = [msg characterAtIndex:i];

    NSLog(@%C --- %i,caractere,caractere); < affiche rien.

    NSCharacterSet* nscs = [NSCharacterSet lowercaseLetterCharacterSet];
    //if((caractere>=(unichar)'a') && (caractere<=(unichar)'z'))
    if([nscs characterIsMember:caractere])
    {
    v = 'a'+intCles;
    if (v<'a'){v = (((caractere-'z')+intCles)%26)+'z';}
    else{v = (((caractere-'a')+intCles)%26)+'a';}
    }

    else if((caractere>='A') && (caractere<='Z'))
    {
    v = 'A'+intCles;
    if (v<'A'){v = (((caractere-'Z')+intCles)%26)+'Z';}
    else{v = (((caractere-'A')+intCles)%26)+'A';}

    }

    else { v=caractere; }

    sortie = [NSString stringWithFormat:@%@%c",sortie,v] ;

    }

    NSLog(@<; %@ >",sortie);
    return sortie;
    }


  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #20
    for(int i ; i < msg.length ; i++)
    {
    ...
    }

    1. T'as utiliser int au lieu de NSUInteger (msg.length est NSUInteger). ça devrait être :

    for(NSUInteger i = 0; i < msg.length ; i++)
    {
    ...
    }

    2. Tu n'as pas initialiser i ; du coup, sa valeur est indéterminée


    3. Tu continues à  utiliser les noms brefs ; pour la maintenabilité du code, la lisibilité est beaucoup plus important que la brièveté
  • Tu dis que le code vigenère est une chaà®ne de même longueur que le message à  coder, mais ce n'est pas ça. En fait c'est un code cyclique qui se répéte sans cesse. Exemple :


     


    Code vigenère "abc"


    Message à  coder          "Demain, je mange une pizza." - 27 caractères


    Séquence de codage :  "abcabcabcabcabcabcabcabcabc" - 27 caractères


     


    Plutôt que de fabriquer une longue chaà®ne de codage, il est plus simple d'utiliser un objet calculant la valeur du décalage à  un moment t, en gérant lui-même la répétition des cycles.


     


    Exemple en Swift (oui je sais, ta drogue c'est l'Objective-C, mais les principes sont les mêmes) :


    a



    class CodeCyclique {

    private var position = 0
    private var listeDecalages = [UInt32]()

    init(codeVigenere:String) {
    for c in codeVigenere.unicodeScalars {
    listeDecalages.append(c.value)
    }
    }

    func decalageCyclique() -> UInt32 {
    let decalage = listeDecalages[position]
    position += 1
    if position == listeDecalages.count {
    position = 0
    }
    return decalage
    }

    }


    a


    A sa création, la classe CodeCyclique() reçoit un texte dont les caractères sont convertis en entiers et stockés dans un tableau. 


    a



    let codeCyclique = CodeCyclique(codeVigenere: "abc")

    a


    A chaque appel de la méthode decalageCyclique(), l'objet fournit la valeur de décalage courante, tout en gérant le cycle de rotation. Par exemple, pour obtenir les 8 premières valeurs de décalage, il faut appeler la méthode 8 fois :



    let codeCyclique = CodeCyclique(codeVigenere: "abc")

    for _ in 1...8 {
    print (codeCyclique.decalageCyclique())
    }


    Affichage :


     



     


    97


    98


    99


    97


    98


    99


    97


    98


     


     


     


    Voici une version du code de Vigenère, quasi-identique à  ma version Swift du code de Caesar. La seule différence est l'utilisation d'un


    décalage cyclique au lieu d'une valeur constante.



    func codageVigenere(message:String, vigerene:String) -> String {

    var resultat = String()
    let leCode = CodeCyclique(codeVigenere: vigerene)

    for c in message.unicodeScalars {
    let decalage = leCode.decalageCyclique()
    let codeVigenere = c.value + decalage
    if let nouveauCaractere = UnicodeScalar(codeVigenere) {
    resultat.append(String(nouveauCaractere))
    } else {
    print ("Attention, erreur de conversion Unicode !!")
    }
    }
    return resultat
    }


    Exemple de code :



    let textePublic = "AAAAAAAAAA"
    let texteVigenere = codageVigenere(message: textePublic, vigerene: "abc")
    print (textePublic)
    print (texteVigenere)


    a


    Résultat des courses :


    a


     



     


    AAAAAAAAAA


    ¢£¤¢£¤¢£¤¢



     


    En reprenant la phrase du début, cela donne :


     



     


    Demain, je mange une pizza.


    Â¥çàà‚à‹à‘àà†àà‚ààŠà†à˜àçà‘à‹àà›àƒ


     

  • DrakenDraken Membre
    janvier 2017 modifié #22

    Le décodage, c'est exactement la même chose que le codage en inversant le sens du décalage cyclique.


    a



    func decodageVigenere(message:String, vigerene:String) -> String {

    var resultat = String()
    let leCode = CodeCyclique(codeVigenere: vigerene)

    for c in message.unicodeScalars {
    let decalage = leCode.decalageCyclique()
    // Soustraction du décalage
    let codeVigenere = c.value - decalage
    if let nouveauCaractere = UnicodeScalar(codeVigenere) {
    resultat.append(String(nouveauCaractere))
    } else {
    print ("Attention, erreur de conversion Unicode !!")
    }
    }
    return resultat
    }


    a


    Exemple :


    a



    let textePublic = "Demain, je mange une pizza."
    let texteVigenere = codageVigenere(message: textePublic, vigerene: "abc")
    let texteDecodage = decodageVigenere(message: texteVigenere, vigerene: "abc")

    print ("Texte original : ", textePublic)
    print ("Version Vigenère : ", texteVigenere)
    print ("Aprés décodage : ", texteDecodage) 

    a


    Affichage :


     



     


    Texte original   :  Demain, je mange une pizza.


    Version Vigenère :  Â¥çàà‚à‹à‘àà†àà‚ààŠà†à˜àçà‘à‹àà›àƒ


    Aprés décodage   :  Demain, je mange une pizza.


     


     


     


    Et c'est tout ..  :)


  • Joanna CarterJoanna Carter Membre, Modérateur
    Et c'est vachement superbe !


    Mais je crois que NSProbleme ne veut que jouer avec les lettres A-Z/a-z, ignorant les lettres accentuées ou tout autres caractères. Ce qui me dit que c'est surtout un exercice académique, pas pour apprendre comment bien coder.


    NSProbleme, ai-je raison ?
  • NSProblemeNSProbleme Membre
    janvier 2017 modifié #24

    En fait c'est juste pour voir les algorithmes de cryptage j'ai encore 5 ou 6 algo à  coder (playfair, hill, DES, ect), on a le choix entre coder en objectif-c ou android, on peut aussi le faire en swift, j'aurais du le faire en swift ça n'a pas l'air plus compliqué que les autres langages  mais comme on a pas de cours sur swift et que je connait plutôt bien android j'ai pris objective-c ^^.


     


    Après pour prendre en compte tous les caractères, y a vraiment d'instruction la dessus, j'adapterai s'il faut ^^.


     


    J'ai réussi à  faire tourner les deux méthode César et Vigenère.


    Merci de vos aides




  • Et c'est vachement superbe !


    Mais je crois que NSProbleme ne veut que jouer avec les lettres A-Z/a-z, ignorant les lettres accentuées ou tout autres caractères. Ce qui me dit que c'est surtout un exercice académique, pas pour apprendre comment bien coder.

     




     


    C'est une occasion comme une autre d'entraà®ner mes "muscles pédagogiques". J'envisage de rédiger une série de tutos sur la programmation et je cherche à  réveiller mes réflexes de "vulgarisateur", endormis depuis trop longtemps.

  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #26

    @NSProbleme


     


    Peut-être tu crois que tu as compris comment coder l'algo Caesar mais ton code reste vachement bouleversant, avec beaucoup de conditions compliquées et les noms insensés.


     


    Voice le code, nettoyé et avec les noms qui sont presque autodocumentant ; ce qui t'aidera quand le jour arrive de le revisiter :



    + (NSString*)substituerEnCaesar:(NSString*)message decalage:(unsigned short)decalage action:(SubstitutionAction)action
    {
    NSMutableString *resultat = [NSMutableString string];

    for (NSUInteger i = 0 ; i < message.length ; i++)
    {
    unichar caractere = [message characterAtIndex:i];

    BOOL caractereMiniscule = [[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:caractere];

    BOOL caractereMajuscule = [[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:caractere];

    unichar aCaractere;

    unichar caractereModifie;

    if (caractereMiniscule || caractereMajuscule)
    {
    aCaractere = caractereMiniscule ? 'a' : 'A';

    unsigned short caractereBaseDeA = caractere - aCaractere;

    if (action == Crypter)
    {
    unichar caractereBaseDeADecale = caractereBaseDeA + decalage;

    caractereModifie = (caractereBaseDeADecale % 26) + aCaractere;
    }
    else
    {
    short caractereBaseDeADecale = caractereBaseDeA - decalage;

    if (caractereBaseDeADecale < 0)
    {
    caractereBaseDeADecale += 26;
    }

    caractereModifie = (caractereBaseDeADecale % 26) + aCaractere;
    }
    }
    else
    {
    caractereModifie = caractere;
    }

    [resultat appendString:[NSString stringWithCharacters:&caractereModifie length:1]];
    }

    return resultat;
    }

    Mais, si tu essaies de crypter les caractères accentués, tu verras pourquoi Drake est moi t'avons conseillé d'abandonner cet algorithme qui, franchement, est bien périmé


Connectez-vous ou Inscrivez-vous pour répondre.