//
/* ------------------------------------------------------------------------------------------------------
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;i0) // 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;
}
}
// 戻る