//
/* ---------------------------------------------------------------------------------------------- decipher.java 暗号解読 ver. 2.00 (JDK 1.02) ueyama@infonet.co.jp 2002.12.25 update: 2007.08.19 ---------------------------------------------------------------------------------------------- */ import java.applet.*; import java.awt.*; import java.util.*; public class decipher extends Applet implements Runnable { String Text[][]={{" the instructions which govern this operation must be", // Neumann "given to the device in absolutely exhaustive detail.", " they include all numerical information which is", "required to solve the problem under consideration:", "initial and boundary values of the dependent variables,", "values of fixed parameters, tables of fixed functions", "which occur in the statement of the problem."}, {" in the control and protective circuits of complex", // Shannon "electrical systems it is frequently necessary to make", "intricate interconnections of relay contacts and", "switches. examples of these circuits occur in automatic", "telephone exchanges, industrial motor control equipment", "and in almost any circuits designed to perform complex", "operations automatically. "}}; int Frqn[]= {64,12,24,32,100,18,16,44,58,1,5,33,20,57,61,16,1,49,52,74,22,8,16,2,14,1}; // 文字使用頻度 int Frqc[]= new int[31]; // 暗号文中の文字使用数 int Keyx[]= { 5,107,61,51,46,74,97,120,161,143,166,189,153,130,184,207,0,69,28,92,138,84,23,39,115,15}; int Keyy[]= {23, 46,46,23, 0,23,23, 23, 0, 23, 23, 23, 46, 46, 0, 0,0, 0,23, 0, 0,46, 0,46, 0,46}; int T=0, K=1; // 暗号文、暗号鍵 int Qtyc; // 暗号文の文字数 int Gx=28, Gy=514, Kx=559, Ky=458; // グラフ目盛、キーボードの表示座標 int Lp=52; // 暗号文表示 行ピッチ int Sn; // 解読文字 No. String Key[] ={"abcdefghijklmnopqrstuvwxyz.,:? ", // 文字データ "hulqcjaksoepiwgtmvydrzxfnb.,:? ", // 暗号鍵 11 "lqrzvhgwejyausxpitmofkncdb.,:? ", // 暗号鍵 12 "createdrandomsecretkeyhere.,:? ", // 暗号鍵 1R "ewfobrqhcdxjknlpitmyausgzv.,:? ", // 暗号鍵 21 "tmyglpehauzvjknscwfobrqdxi.,:? ", // 暗号鍵 22 "createdrandomsecretkeyhere.,:? "}; // 暗号鍵 2R int Keyi[]= new int[31]; // 解読データ boolean Sf=false; // true: 解読の途中 Image Img; Thread th=null; Graphics gx; int T0=0, T1=0; 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){}; for(int i=0; i<31; i++) Keyi[i]=-1; cip_cnt(); // 暗号文 文字数カウント new_key(3); new_key(6); // 暗号鍵の生成 gx=getGraphics(); } public void start() { if(th==null) { th=new Thread(this); th.start(); } } 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 m, int n, int c) { int w=0, h=0, ox=0, oy=0; switch(c) { case 0: w= 14; h=18; ox= 0; oy= 0; break; // 文字 (暗号文 平文 グラフ キートップ) case 1: w= 18; h= 7; ox= 0; oy=72; break; // グラフ目盛 "XX%" case 2: w= 20; h=20; ox=364; oy=54; break; // キートップ case 3: w= 90; h= 9; ox= 0; oy=90; break; // 凡例 case 4: w= 31; h=19; ox=404; oy=54; break; // CLR キー case 5: w= 83; h=11; ox= 0; oy=79; break; // "文字の使用頻度" case 6: w=227; h=14; ox= 0; oy=99; break; // 暗号文・暗号鍵の変更 case 7: w= 6; h=10; ox=227; oy=99; break; // ラジオボタン 黒丸 } Graphics gr=getGraphics(); gr.clipRect(x,y,w,h); if(!(c==0 && n==3)) gr.clearRect(x,y,w,h); gr.drawImage(Img,x-(ox+m*w),y-(oy+n*h),this); gr.dispose(); } public void cip_cnt() // 暗号文 文字数カウント { int i,j,n; Qtyc=0; for(i=0; i<31; i++) Frqc[i]=0; for(j=0;j<7;j++) { for(i=0;i戻る=0)?Keyi[n]:30, 1, 0); // 解読済み文字の表示 } } for(i=0; i<8; i++) // グラフ目盛線の表示 { if(i==0) gx.setColor(new Color(102,102,102)); else gx.setColor(new Color(204,204,204)); gx.drawLine(Gx-6, Gy-16*i, Gx+520, Gy-16*i); dsp_g(0, Gy-16*i-3, i, 0, 1); // % の表示 } for(i=0; i<26;i++) { m=de_ciph(i); dsp_grf(m*20+Gx, Frqc[m]*800/Qtyc, (Keyi[m]>=0)?0:1); // 暗号文文字使用頻度グラフの表示 n=Key[K].indexOf(Key[0].charAt(i)); dsp_grf(i*20+Gx+7, Frqn[i], (deciph(i))?2:3); // 英文の文字使用頻度グラフの表示 dsp_g(n*20+Gx, Gy+8, n, 0 ,0); // グラフの文字の表示 dsp_g(i*20+Gx, Gy+28, (Keyi[i]>=0)?Keyi[i]:30, 1, 0); // 解読済み文字の表示 dsp_g(Kx+Keyx[i], Ky+Keyy[i], (deciph(i))?0:1, 0, 2); // キートップの表示 dsp_g(Kx+Keyx[i]+3, Ky+Keyy[i]+1, i, 3, 0); // キーの文字の表示 } dsp_g(350, 388, 1, 0, 3); // 凡例 "一般英文文字頻度" dsp_g(454, 388, 0, 0, 3); // 凡例 "暗号文の文字頻度" } public int de_ciph(int s) // 一文字解読 { int i; for(i=0; i<31; i++) if(Key[0].indexOf(Key[K].charAt(i))==s) break; return i; } public boolean deciph(int s) // 解読済みか? { int i; for(i=0; i<31; i++) if(Keyi[i]==s) break; return (i<31)?true:false; } public void new_key(int k) // 暗号鍵(ランダム)の生成 { int i,j,d,n=0, ex[]=new int[26]; Random rnd=new Random(); for(i=0; i<26; i++) ex[i]=Math.abs(rnd.nextInt()); for(i=0; i<26; i++) { d=0; for(j=0; j<26; j++) {if(ex[j]>d) {d=ex[j]; n=j;}} ex[n]=0; Key[k]=Key[k].substring(0,n)+Key[0].substring(i,i+1)+Key[k].substring(n+1); } } public void paint(Graphics g) { g.clearRect(0,0,size().width,size().height); dsp_grph(); // 暗号・解読文の表示 dsp_g( 2, 382, 0, 0, 5); // "文字の使用頻度" dsp_g(Kx+184, Ky+47, 0, 0, 4); // CLR ボタン dsp_g(Kx, Ky+86, 0, 0, 6); // 暗号文・鍵 変更部 dsp_g(Kx+T*32+53, Ky+86, 0, 0, 7); // 暗号文 ラジオボタン dsp_g(Kx+(K-1)%3*32+153, Ky+86, 0, 0, 7); // 暗号鍵 ラジオボタン } public void run() { int i,j,n; while(th!=null) { try { th.sleep(128); } catch (InterruptedException e){}; T0++; if(Sf && T0%5==0 && Sn<26) { T1++; if(Sf) dsp_g(Sn*20+Gx,Gy+8,Sn,(T1%2==0)?0:1,0); // グラフの文字をウインク for(j=0;j<7;j++) { for(i=0;i 400 && inside(mx,Gx,Gx+520)) // 解読文字指定 グラフ領域をクリック { Sn=(mx-Gx)/20; dsp_grf(Sn*20+Gx, Frqc[Sn]*800/Qtyc, 0); // 暗号文文字使用頻度グラフの表示 Sf=true; // 解読中 } else if(my<400 && my%Lp<18) // 解読文字指定 暗号文をクリック { n=Key[0].indexOf(Text[T][my/Lp].charAt(mx/14)); Sn=de_ciph(n); dsp_grf(Sn*20+Gx, Frqc[Sn]*800/Qtyc, 0); // 暗号文文字使用頻度グラフの表示 Sf=true; // 解読中 } if(inside(x, 36, 102) && y>85) // 暗号文の変更 { dsp_g(Kx+T*32+53, Ky+86, 1, 0, 7); // 暗号文 ラジオボタン T=(x-36)/32; // 新暗号文 dsp_g(Kx+T*32+53, Ky+86, 0, 0, 7); // 暗号文 ラジオボタン K=(K-1)%3+T*3+1; // 新暗号鍵 for(i=0; i<31; i++) Keyi[i]=-1; // 解読データのクリア gx.clearRect(0,0,size().width,360); cip_cnt(); // 新暗号文の文字数カウント dsp_grph(); // 新暗号文の表示 } if(inside(x, 137, 227) && y>85) // 暗号鍵の変更 { dsp_g(Kx+(K-1)%3*32+153, Ky+86, 1, 0, 7); // 暗号鍵 ラジオボタン K=(x-137)/30+T*3+1; // 新暗号鍵 dsp_g(Kx+(K-1)%3*32+153, Ky+86, 0, 0, 7); // 暗号鍵 ラジオボタン if(K==3 || K==6) new_key(K); // 暗号鍵(ランダム)の生成 cip_cnt(); // 新暗号文の文字数カウント dsp_grph(); // 新暗号文の表示 } if(inside(x, 184, 215) && inside(y, 46, 66)) // クリアボタン { for(i=0; i<31; i++) Keyi[i]=-1; // 解読データのクリア dsp_grph(); // 暗号・解読文の表示 } return true; } public void stop() { if(th!=null) { th.stop(); th=null; } } } //