編寫程序,要求輸入一個字符串,然后輸入一個句子作為凱撒加密算法的密鑰,然后輸出該字符串加密后的結果。
舉例如下:使用改進版caesar密碼,密鑰為I love my country!,明文為I am in danger!,計算出密文。
小寫明文字母和大寫密文字母的映射關系表如下圖1,構造方法如下:第一行明文字母填寫就是26個字母按順序寫,第二行密文字母順序就是先把密鑰句子(I love my country,注意重復字母去掉)寫入密文字母里,然后再清點26個字母中沒有寫進密文的剩下字母按照字母表順序依次寫完。
明文 |
a |
b |
c |
d |
e |
f |
g |
h |
i |
j |
k |
l |
m |
n |
o |
p |
q |
r |
s |
t |
u |
v |
w |
x |
y |
z |
密文 |
I |
L |
O |
V |
E |
M |
Y |
C |
U |
N |
T |
R |
A |
B |
D |
F |
G |
H |
J |
K |
P |
Q |
S |
W |
X |
Z |
|-----密鑰句子去掉重復字母-----||---26個字母剩下的按字母表順序寫入---|
圖1 小寫字母的映射表
因為密文是去掉標點符號后全部都是大寫輸出,究其原因是為了敵人(破譯者)根據空格和標點符號和首字母大寫等習慣猜出哪些字母在一起是一個完整單詞。所以我們譯文要去掉所有標點符號而且把所有字母都變成大寫。所以根據圖1我們得出圖2大寫字母對應的映射表,就是把圖1的第一行全部變成大寫即可。
明文 |
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
密文 |
I |
L |
O |
V |
E |
M |
Y |
C |
U |
N |
T |
R |
A |
B |
D |
F |
G |
H |
J |
K |
P |
Q |
S |
W |
X |
Z |
|-----密鑰句子去掉重復字母-----||---26個字母剩下的按字母表順序寫入---|
圖2 大寫字母的映射表
有了映射關系表,然后明文為I am in danger!,密文為UIAUBVIBYEH,注意密文一定是大寫,所以密文是去掉標點符號后所有大小寫都變成大寫的密文輸出。
代碼實現:
/* 實現進階版凱撒密碼 */ import java.util.ArrayList; import java.util.Scanner; public class Caesar { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("明文:"); String mingwen = sc.nextLine(); System.out.print("密鑰:"); String key = sc.nextLine(); String st = kaesarUpVersion(removeSymbol(mingwen),getKey(removeSymbol(key))); System.out.println("密文:"+st); } //實現將其他字符刪除 public static String removeSymbol(String s){ //創建一個字符串生成器 StringBuilder sb = new StringBuilder(); //遍歷字符串s for (int i = 0; i <s.length() ; i++) { //取出字符串中的每個字符 char ch = s.charAt(i); //如果字符是字母,添加到字符串生成器 if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ sb.append(ch); } } //轉換成字符串 String str = sb.toString(); return str.toUpperCase();//以大寫字母返回 } //傳入一個字符串,實現密文,並以大寫字符串形式返回 public static String getKey(String string){ //創建一個動態數組對象 ArrayList<String> list = new ArrayList<>(); //遍歷字符串 for (int i = 0; i <string.length() ; i++) { //用substring取出單個字符,並變為大寫,賦值給st String st = string.substring(i,i+1).toUpperCase(); //使用contains函數,對數組內元素進行比較,皆不同時,添加進數組 if (!list.contains(st)){ list.add(st); } } //添加剩余的字母,形成映射表 for (char i = 65; i <=90 ; i++) { //valueOf函數將char類型轉化為String類型 String str = String.valueOf(i); if (!list.contains(str)){ list.add(str); } } //創建字符串生成器對象 StringBuilder stringBuilder = new StringBuilder(); //將list數組的元素依次添加到生成器中 for (String s : list) { stringBuilder.append(s); } //轉換為字符串,並返回 String end = stringBuilder.toString(); return end; } //根據明文和密鑰,進行加密 public static String kaesarUpVersion(String s, String key){ //將字符串轉換成char類型的數組 char[] charS = s.toCharArray(); char[] charKey = key.toCharArray(); //創建字符串生成器 StringBuilder builder = new StringBuilder(); //遍歷明文字符數組,由對應關系產生密文 for (int i = 0; i <charS.length ; i++) { int j = charS[i]-65; builder.append(charKey[j]); } //轉換為字符串並輸出 String miwen = builder.toString(); return miwen; } }