2栏栅栏密码:
比如明文:THERE IS A CIPHER
去掉空格后变为:THEREISACIPHER
两个一组,得到:TH ER EI SA CI PH ER
先取出每行第一个字母:TEESCPE
再取出每行第二个字母:HRIAIHR
连在一起就是:TEESCPEHRIAIHR
而解密的时候,先把密文从中间分开,变为两行:
T E E S C P E
H R I A I H R
再按上下上下的顺序组合起来:
THEREISACIPHER
分出空格,就可以得到原文了:
THERE IS A CIPHER
主要像是矩阵,以列为顺序依次取数。
------------------------------------------------
多栏栅栏密码:
明文:THERE IS A CIPHER
七个一组:THEREIS ACIPHER
抽取字母:TA HC EI RP EH IE SR
组合得到密码:TAHCEIRPEHIESR
可以通过分析密码的字母数来解出密码
比如:TAHCEIRPEHIESR
一共有14个字母,可能是2栏或者7栏
尝试2栏--》失败
尝试7栏--》成功
-------------------------------------------------
当字母数m为偶数时,分栏数可能是其因子
当字母数m为奇数时,可能是前m-1个均分,最后一个独自成行,当然也可能m+1均分,任意分都有可能
-----------------------------------------------------------------------------------------
完整测试例子如下:
import java.util.Scanner;
public class 栅栏密码技术 {
public static String quitBlank(String normalStr){
StringBuffer sBuffer=new StringBuffer();
for (int i = 0; i < normalStr.length(); i++) {
if(normalStr.charAt(i)!=' ')
sBuffer.append(normalStr.charAt(i));
}
return sBuffer.toString();
}
public static String En(int n,String Mstr){
StringBuffer result=new StringBuffer();
int step=(int)((double)Mstr.length()/n+0.5);
String[] splitStr=new String[n];
int temp=0;
for (int i = 0; i < n; i++) {
if(temp+step
splitStr[i]=Mstr.substring(temp, temp+step);
else
splitStr[i]=Mstr.substring(temp, Mstr.length());
temp+=step;
}
for (int i = 0; i < step; i++) {
for (int j = 0; j < n; j++) {
if(i
result.append(splitStr[j].charAt(i));
}
}
}
return result.toString();
}
public static String Dn(int n,String Mstr){
StringBuffer result=new StringBuffer();
int step=(int)((double)Mstr.length()/n+0.5);
String[] splitStr=new String[step];
int temp=0;
for (int i = 0; i < step; i++) {
if(temp+n
splitStr[i]=Mstr.substring(temp, temp+n);
else
splitStr[i]=Mstr.substring(temp, Mstr.length());
temp+=n;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < step; j++) {
if(i
result.append(splitStr[j].charAt(i));
}
}
}
return result.toString();
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("第一行输入明文字符\n"
+ "第二行输入分栏数n");
String normalStr=scan.nextLine();
int n=scan.nextInt();
String Mstr=quitBlank(normalStr);
String EnStr=En(n, Mstr);
System.out.println("密文如下:\n"+ EnStr);
String DnStr=Dn(n, EnStr);
System.out.println("解密后明文如下:\n"+ DnStr);
}
}
运行结果如下:
第一行输入明文字符
第二行输入分栏数n
abcdefghijk
3
密文如下:
aeibfjcgkdh
解密后明文如下:
abcdefghijk
----------------------------------
注意:加密时的分栏数(行数)为解密时的列数
取值时均由上至下按列取值即可。