//
/* ------------------------------------------------------------------------------------------------------ enigma.java エニグマ ver. 1.20 (JDK 1.02) ueyama@infonet.co.jp 2000.03.03 update: 2007.08.16 ------------------------------------------------------------------------------------------------------ */ import java.applet.*; import java.awt.*; import java.lang.Math; import java.util.*; public class enigma extends Applet { int Ref[] ={24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19}; // Reflector の接続 int Refx[]={2,3,4,5,6,7,8,5,5,9,10,8,8,10,8,5,6,3,7,3,4,4,4,9,2,3}; // 同上 表示用縦線位置 int Ro[][]={{21,19,17,4,6,8,10,12,14,5,18,20,22,0,24,2,16,1,7,11,25,9,3,13,15,23}, // Rotor の接続(往路) {13,17,10,9,19,3,8,11,25,21,2,22,6,16,7,5,23,1,15,24,14,4,18,20,12,0}, {6,14,7,23,8,15,10,16,18,11,17,12,9,22,1,5,19,25,20,2,4,13,3,0,24,21}}; int Rh[][]={{13,17,15,22,3,9,4,18,5,21,6,19,7,23,8,24,16,2,10,1,11,0,12,25,14,20}, // Rotor の接続(帰路) {25,17,10,5,21,15,12,14,6,3,2,7,24,0,20,18,13,1,22,4,23,9,11,16,19,8}, {23,14,19,22,20,15,0,2,4,12,6,9,11,21,1,5,7,10,8,16,18,25,13,3,24,17}}; int Qwer[]={16,22,4,17,19,25,20,8,14,0,18,3,5,6,7,9,10,15,24,23,2,21,1,13,12,11}; // キーの配列(文字) int Rewq[]={9,22,20,11,2,12,13,14,7,15,16,25,24,23,8,17,0,3,10,4,6,21,1,19,18,5}; // キーの配列(位置) int Lw[]={10,7,9,8,8,8,9,8,6,6,8,8,8,8,9,7,9,8,7,10,8,10,10,10,10,9}; // 暗号化文字の幅 // キーの座標: q w e r t z u i o a s d f g h j k p y x c v b n m l int Kx[]={ 7,52,97,142,187,232,277,322,367,27,72,117,162,207,252,297,342, 0,45,90,135,180,225,270,315,360,}; int Ky[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0,27,27, 27, 27, 27, 27, 27, 27,54,54,54, 54, 54, 54, 54, 54, 54,}; int X=70, Y=25, Kox=70, Koy=384; // Roter シンボルとキーの表示位置 int Cx=X-55, Cq=0, Ctx[]=new int[80]; // 暗号化文字表示位置、文字数、文字列 int R[]={0,0,0}; // Rotor No. int Key=-1; // キー入力文字 int Crp=-1; // 暗号化文字 Image Img; AudioClip Ac1, Ac2, Ac3; Graphics gr; public void init() { String bg=getParameter("bgcolor"); // 背景色の読み込み int bgc=Integer.valueOf(bg,16).intValue(); setBackground(new Color(bgc)); MediaTracker mt=new MediaTracker(this); Img=getImage(getCodeBase(), getParameter("figure")); // gif ファイルの読み込み mt.addImage(Img, 0); try { mt.waitForID(0); } catch(InterruptedException e){}; Ac1=getAudioClip(getCodeBase(), getParameter("audio_clip_1")); // 効果音データの読み込み Ac2=getAudioClip(getCodeBase(), getParameter("audio_clip_2")); Ac3=getAudioClip(getCodeBase(), getParameter("audio_clip_3")); Random rnd=new Random(); for(int i=0;i<3;i++) R[i]=Math.abs(rnd.nextInt())%26; // 乱数による Rotor の初期設定 gr=getGraphics(); } public boolean inside(int x, int a, int b) { return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false; } public void dsp_g(int x, int y, int ver, int hol, int n) // 画像の表示 { int w=0,h=0, ox=0,oy=0; switch(n) { case 0: w= 11; h= 11; ox= 0; oy= 95; break; // 文字 (alphabet) case 1: w= 25; h= 20; ox= 0; oy= 0; break; // Rotor 回転位置 case 2: w= 26; h= 21; ox=364; oy=118; break; // Rotor INC ボタン case 3: w= 26; h= 21; ox=416; oy=118; break; // Rotor DEC ボタン case 4: w= 26; h= 22; ox=286; oy=118; break; // CLR ボタン case 5: w= 25; h= 25; ox= 0; oy= 20; break; // キー case 6: w= 52; h= 11; ox=286; oy= 95; break; // "Reflector" case 7: w= 61; h= 11; ox=338; oy= 95; break; // "Slow Rotor" case 8: w= 74; h= 11; ox=399; oy= 95; break; // "Medium Rotor" case 9: w= 60; h= 11; ox=473; oy= 95; break; // "Fast Rotor" case 10: w= 26; h= 11; ox=533; oy= 95; break; // "Lamp" case 11: w= 18; h= 11; ox=559; oy= 95; break; // "Key" case 12: w= 6; h= 5; ox=468; oy=118; break; // 矢印 case 13: w= 10; h= 12; ox=286; oy=106; break; // 暗号化文字 } Graphics gx=gr.create(); gx.clipRect(x,y,w,h); gx.drawImage(Img,x-(ox+w*hol),y-(oy+h*ver),this); gx.dispose(); } public int dsp_ref(int n, int c) // Reflector の表示 { int x=X-Refx[n]*5-6, y0=Y+n*12+5, y1=Y+Ref[n]*12+5; gr.setColor(new Color(c)); gr.drawLine(X,y0,x,y0); gr.drawLine(X,y1,x,y1); gr.drawLine(x,y0,x,y1); return Ref[n]; } public int dsp_rotor(int n, int r, int c, boolean d) // Rotor の表示 (d: true=往路) { int l=2, x=X+120*r, y1=(R[r]+n)%26, y2=(d)? (Ro[r][n]+R[r])%26:(Rh[r][n]+R[r])%26; gr.setColor(new Color(c)); gr.drawLine(x+((d)?119:51), Y+y1*12+5, x+((d)?51:119), Y+y2*12+5); // 配線の表示 if(c>0) l=(d)? 5:6; // 文字の表示色 int y=(d)? y1:y2; dsp_g(X+r*120+120,Y+y*12,l,(R[r]+26-y)%26,0); // Rotor 文字の表示 (右) y=(d)? y2:y1; dsp_g(X+r*120+ 40,Y+y*12,l,(R[r]+26-y)%26,0); // Rotor 文字の表示 (左) return y2; } public int inc_roter() // Rotor の回転 { int i=2; R[2]=(R[2]+1)%26; // Fast Rotor if(R[2]==0) { R[1]=(R[1]+1)%26; i--; // Medium Rotor if(R[1]==0) { R[0]=(R[0]+1)%26; i--; // Slow Rotor } } return i; } public void clr_rotor(int r) // Rotor の表示消去 { gr.setColor(new Color(224,224,240)); gr.fillRect(X+r*120+40+11,Y+5,69,301); } public void dsp_key(int n, int c) // キーボードのキーの表示 { gr.setColor(new Color(0,0,0)); gr.fillOval(Kx[n]+Kox-2,Ky[n]+Koy-2,29,29); // 黒い円を描く dsp_g(Kx[n]+Kox,Ky[n]+Koy,c,Qwer[n],5); // 文字を表示 } public void drw_line(int x0, int x1, int x2, int n, int d, int c) // 水平線と矢印の表示 { if(c==0) gr.clearRect(x0,n*12+28,6,5); // 矢印の消去 else dsp_g(x0, n*12+28,0,d,12); // 矢印の表示 gr.drawLine(X+x1,Y+n*12+5,X+x2,Y+n*12+5); // 水平線の表示 } public int dsp_route(int c) // 暗号化経路の表示 { int n=Key, r; gr.setColor(new Color(c)); drw_line(443,371,439,n,0,c); // 水平線と矢印の表示 dsp_g(X+440,Y+n*12,(c==0)?1:3,n,0); // key board の表示 dsp_g(X+400,Y+n*12,0,n,0); // Lamp board の表示 for(r=2; r>=0; r--) // Rotor の表示(往路) { n=dsp_rotor((n+26-R[r])%26,r,c,true); // Rotor 内部結線の表示 drw_line(83+r*120, r*120+11, r*120+40-1, n,0,c); // 水平線と矢印の表示 } dsp_g(X,Y+n*12,(c==0)?2:4,n,0); // Reflector 文字の表示 n=dsp_ref(n, c); // Reflector 内部結線の表示 dsp_g(X,Y+n*12,(c==0)?2:4,n,0); // Reflector 文字の表示 for(r=0;r<3;r++) // Rotor の表示(帰路) { drw_line(102+r*120, r*120+11, r*120+40-1, n,1,c); // 水平線と矢印の表示 n=dsp_rotor((n+26-R[r])%26,r,c,false); // Rotor 内部結線の表示 } drw_line(462,371,399,n,1,c); // 水平線と矢印の表示 dsp_g(X+400,Y+n*12,(c==0)?0:4,n,0); // Lamp の表示 return n; } public void dsp_cip(int c) // 暗号文の表示 { if(Cx<515) dsp_g(Cx,Koy-26,0,c,13); // 暗号化文字の表示 Cx+=(Lw[c]+1); // 表示位置の更新 } public void paint(Graphics g) { int i=0,j, x=0, y=0, r; g.setColor(new Color(224,224,240)); g.fillRect(X-61,Y,61,311); // Reflector の塗りつぶし for(r=0;r<3;r++) { g.fillRect(X+r*120+56-5,Y,69,311); // Rotor の塗りつぶし dsp_g(X+r*120+ 41,0,0,0,2); // Rotor INC ボタン dsp_g(X+r*120+ 73,1,0,R[r],1); // ローター設定 No. dsp_g(X+r*120+104,0,0,0,3); // Rotor DEC ボタン } g.setColor(new Color(0,0,0)); for(i=0;i<26;i++) { for(r=0;r<3;r++) g.drawLine(X+r*120+5,Y+i*12+5,X+r*120+40+5,Y+i*12+5); // 水平線の表示 g.drawLine(X+365,Y+i*12+5,X+445,Y+i*12+5); // 水平線の表示 dsp_ref(i,0); dsp_g(X,Y+i*12,2,i,0); // Reflector の表示 dsp_g(X+400,Y+i*12,0,i,0); // Lamp の表示 dsp_g(X+440,Y+i*12,1,i,0); // Key の表示 } for(r=0;r<3;r++) // Rotor の表示 { for(i=0;i<26;i++) { j=(R[r]+i)%26; dsp_rotor(j,r,0,true); // Rotor 内部配線の表示 } } dsp_g(14,339,0,0,6); // "Reflector" の表示 dsp_g(365,339,0,0,7); dsp_g(238,339,0,0,8); dsp_g(125,339,0,0,9); // Rotor 名称の表示 dsp_g(462,339,0,0,10); dsp_g(506,339,0,0,11); // "Lamp", "Key" の表示 g.setColor(new Color(153,153,153)); // 暗号文表示エリアの作成 g.drawRect(X-62,Koy-31,514,20); g.setColor(new Color(255,255,255)); g.fillRect(X-61,Koy-30,512,18); Cx=X-55; for(i=0;i戻る0) // CLR ボタンをクリック { dsp_g(485,448,0,1,4); // CLR ボタンを表示 Cq=0; Cx=X-55; gr.setColor(new Color(255,255,255)); gr.fillRect(X-61,Koy-30,513,18); // 暗号文表示をクリア } return true; } public boolean mouseUp(Event e, int mx, int my) { int i,j=0,k,r, n=(mx-(X+35))/120, x=(mx-(X+35))%120; if(inside(n,0,2) && inside(my,0,21)) // Rotor { if(inside(x, 6,32)) dsp_g(X+n*120+ 41,0,0,0,2); // Rotor のボタンの表示を元に戻す if(inside(x,69,95)) dsp_g(X+n*120+104,0,0,0,3); // 同上 } if(inside(Key,0,25)) // Key がクリックされたときの処理 { dsp_route(0x000000); // 暗号化経路を元に戻す k=inc_roter(); // Rotor を回転させる for(r=2;r>=k;r--) // その結果を表示 { clr_rotor(r); for(i=0;i<26;i++) dsp_rotor(i,r,0,true); // Rotor 内部配線の表示 dsp_g(X+r*120+73,1,0,R[r],1); // Rotor の No. の表示 } dsp_key(Rewq[Key],0); dsp_key(Rewq[Crp],0); // キーの表示を元に戻す Ac2.play(); } if(inside(mx,485,511) && inside(my,448,470)) dsp_g(485,448,0,(Cq==0)?2:0,4); // クリアボタンの表示 return true; } } //