2017-01-27 27 views
0

こんにちは私はエラーが含まれていませんが、私は特殊文字に問題があります私は適切な文字の代わりに四角形を持っている私はどのようにスペースに対処するのか分からない私のコード暗号化セザールアルゴリズム

package cesar; 

import java.util.Scanner; 

public class Cesar { 

private static short codeMajuscule=65; 
private static short codeMinuscule=97; 
private static short tailleAlph = 26; 

public static void main(String[] args) { 
Scanner sc=new Scanner(System.in); 
    System.out.println("Entrer la chaine a crypter"); 
    String phrase = sc.next(); 
     System.out.println("entrer votre cle"); 
    int c= sc.nextInt(); 
    System.out.println("la phrase après transformation " + chiffrement(   phrase , c));  
} 

private static String chiffrement(String ch , int n){  

    String chDecripte=""; 
      ch=ch.replaceAll("[éèêë]", "e"); 
      ch=ch.replaceAll("[Ç]", "C"); 
      ch=ch.replaceAll("[ÈÉÊË]", "E"); 
      ch=ch.replaceAll("[ÌÍÎÏ]", "I"); 
      ch=ch.replaceAll("Ñ", "N"); 
      ch=ch.replaceAll("ÒÓÔŒ", "O"); 
      ch=ch.replaceAll("ÙÚÛÜ", "U"); 
      ch=ch.replaceAll("ÝŸ", "Y"); 
      ch=ch.replaceAll("àáâæ", "a");   
      ch=ch.replaceAll("[ÀÁÂÆ]", "A"); 
      ch=ch.replaceAll("[èéêë]", "e");      
      ch=ch.replaceAll("[ìíîï]", "i"); 
      ch=ch.replaceAll("[ñ]", "n"); 
      ch=ch.replaceAll("[òóôœ]", "o"); 
      ch=ch.replaceAll("[ùúûü]", "u"); 
      ch=ch.replaceAll("[ýÿ]", "y"); 

    for(int i = 0 ; i < ch.length() ; i++){ 
     if(ch.codePointAt(i) >= codeMajuscule && 
       ch.codePointAt(i) <= (codeMajuscule + tailleAlph)){ 

      chDecripte += (char) ((ch.codePointAt(i) - codeMajuscule + n) % tailleAlph + codeMajuscule) ; 

     }else if(ch.codePointAt(i) >= codeMinuscule && 
       ch.codePointAt(i) <= (codeMinuscule + tailleAlph)){ 

      chDecripte += (char) ((ch.codePointAt(i) - codeMinuscule + n) % tailleAlph + codeMinuscule) ;  
     }else{ 
      chDecripte += ch.charAt(i); 
     } 
    } 
    return chDecripte; 
} 
} 

と感謝

+0

問題を示す入出力の例を挙げることができますか? – coolioasjulio

+0

私はélèveなどを書いているときには、私はspecil caracterの場所に空の四角があります。私は、私がスペースを持って何かを書くときにもデコードしたいと思っています。コード –

+0

これはあなたのスペースエラーの原因かもしれませんが、あなたは改行線区切り記号を消費していません。 'sc.next();'を 'sc.nextLine()'に置き換えます。これにより、入力行全体が消費されます。 'next()'は次のスペースまで入力のみを消費します。 – coolioasjulio

答えて

0

シーザー暗号は、空白文字を考慮していない通常(常にではない)あなたが選択した場合、彼らは任意のホワイトスペースとなどピリオド、コロン、カンマなどの特殊文字を無視しますそれらを許可する "キー"または "マップ"を作成する必要がありますので、操作を元に戻す方法を知っている。

通常、すべての文字は数値表現(整数形式)を使用して操作できます。それらを数値として扱うと、これははるかに単純な問題になります。特殊文字を使用しているので、あなたはUTF-8形式を使用していると思いますか?あなたは数値上で動作して考えると、「マップ」として、このUTF-8のチャートを使用することがあります:

http://www.utf8-chartable.de/

は、あなたがこれまでに「マップ」としてASCIIサブセットのみを使用してこのチャートを作業している場合:

http://www.asciitable.com/

通常、Cesar暗号を実行するときに考慮する必要があるのは、通常のアルファベットまたは指定された一部の文字の境界内にとどまりたいということです。したがって、文字 'z'(122の整数値)に達すると、右にシフトしている場合、 'a'(97の整数値)に戻ってそこからシフトする必要があります。

例えば、我々は26個の数字は、小文字のアルファベットでそこにいることを知っていると、彼らは97からASCIIの範囲 - だから、あなたは(擬似コード)のようなチェックを行う可能性があります122:

char char_to_shift; /* the character to be shifted */ 

if (char_to_shift + shift_amount > 'z') { 
    tmp = shift_amount - ('z' - char_to_shift); 
    shift_amount = tmp; 
    char_to_shift='a'; 
    char_to_shift+=shift_amount; 
} else { 
    char_to_shift+=shift_amount; 
} 

したがって、上記の中擬似コードは文字5を右(ROT-5)にシフトし、その文字が「x」(120の整数値)であると仮定します。私たちは '{'文字である125にシフトしたでしょう。代わりに、 'z'(122) - 'x'(120)を使って2を残します。次にshift_amount(5)からその値を減算して、3を残します。次にchar_to_shiftを 'a'にリセットし、残量3を「c」で終わるようにシフトさせます。

大文字アルファベットと小文字アルファベットの間には、大文字に小文字をシフトすることを許可する場合に考慮する必要があることに注意してください。

独自の「値のマップ」を生成するには、上記の表が探しているものに合わない場合は、許可された文字のサブセット内の各文字の小数点値を出力してみてください。

0

次のコードは正しくありません:すべての

... 
}else if(ch.codePointAt(i) >= codeMinuscule && 
     ch.codePointAt(i) <= (codeMinuscule + tailleAlph)){ 

    chDecripte += (char) ((ch.codePointAt(i) - codeMinuscule + n) % tailleAlph + codeMinuscule) ;  
}else{ 
    chDecripte += ch.charAt(i); 
} 

は、まず、あなたの入力はすべて大文字ではないかもしれません。しかし何らかの理由で2番目のラインが突然アップの代わりにカウントダウンしているように見えます。解読中にのみそれを行うべきです。また、if文は<=>=を使用し、=文字は明らかに以前のifで覆われています。

最後に、elseは、ifelse ifの記述でカバーされているため、決して届きません。


私の中にいくつかのヒントを代替ソースコードを作成しました:

import java.text.Normalizer; 
import java.util.Scanner; 

public class Cesar { 

    // unchanged 
    public static void main(String[] args) { 
     Scanner sc = new Scanner(System.in); 
     System.out.println("Entrer la chaine a crypter"); 
     String phrase = sc.next(); 
     System.out.println("entrer votre cle"); 
     int c = sc.nextInt(); 
     System.out.println("la phrase après transformation " + chiffrement(phrase, c)); 
    } 

    // you can directly show what you are doing by using 'A' and 'Z' 
    private static int CODE_MAJESCULE = 'A'; 
    // you may actually not need constants for this 
    private static int CODE_MINESCULE = 'Z'; 
    // the TAILLE_ALPH is of course the difference of those two 
    private static int TAILLE_ALPH = CODE_MINESCULE - CODE_MAJESCULE + 1; 

    // split out into separate methods whereever possible 
    private static String normalise(String phrase) { 
     // probably better to change Æ into AE 
     // but 
     String doublesRemoved = phrase.replaceAll("Æ", "a").replaceAll("Œ", "o"); 
     doublesRemoved = doublesRemoved.replaceAll("æ", "a").replaceAll("œ", "o"); 
     // separates character and diacritic (ë becomes e + " in a way) 
     String separated = Normalizer.normalize(doublesRemoved, Normalizer.Form.NFD); 
     // this will also remove all non-western characters 
     String accentsRemoved = separated.replaceAll("[^\\p{ASCII}]", ""); 
     // and finally, we only seem to handle uppercase 
     return accentsRemoved.toUpperCase(); 
    } 

    private static String chiffrement(String phrase, int cle) { 

     // first normalize the message so we can handle it 
     String phraseNormalise = normalise(phrase); 

     // use a StringBuilder (or the right size) for adding characters in loops 
     StringBuilder chiffre = new StringBuilder(phraseNormalise.length()); 
     for (int i = 0; i < phraseNormalise.length(); i++) { 
      // codePointAt doesn't play nice with String.length() 
      // and it's now all ASCII anyway 
      char v = phraseNormalise.charAt(i); 

      // --- filter out special characters 
      if (v < CODE_MAJESCULE || v > CODE_MINESCULE) { 
       chiffre.append(v); 
       // most Java programmers use continue for "guards" 
       continue; 
      } 

      char c = cesar(v, cle); 

      chiffre.append(c); 
     } 

     // ... and return 
     return chiffre.toString(); 
    } 

    private static char cesar(char v, int cle) { 
     // --- convert into element e in [0..TAILLE_ALPH) 
     int e = v - CODE_MAJESCULE; 

     // --- perform the cesar chiffre 
     int cc = (e + cle) % TAILLE_ALPH; 

     // --- convert back into A .. Z 
     char c = (char) (cc + CODE_MAJESCULE); 
     return c; 
    } 
} 

は、最も重要なことは、シーザーが別の行に自分自身を暗号化実行。これにより、物事を正しく得ることがずっと簡単になります。

サブ問題の問題を打ち破り(そして別々にテストする)ことは、プログラミングの最も重要なスキルの1つです。そうすることを決して忘れないでください。

+0

大変ありがとうございますが、結果に特別なキャラクターを入力すると、スペースも処理されません。入力するとエラーが表示されます –

+0

はい、まあ、あなたのアルファベットを拡大するか*または文字を保持または削除します。他のエラーはあなた自身のコードに既にあります。 'next()'を 'nextLine()'に置き換えるだけで、次の空白まで読み込まれます。オリジナルのシーザー暗号は、通常の文字を含む1つのアルファベットでのみ動作します。 –