栅栏加密解密的分析和实现

1、栅栏加密

栅栏加密就是将明文按照顺序分成n组,然后将这n组,组合成一个密文。

比如以加密字符串“abcdefghijklm”为例

分成3组,加密过程如下:

a

d

g

j

m

b

e

h

k

 

c

f

i

l

 

得到密文:adgjmbehkcfil

如果分成4组,那么结果如下:

a

e

i

m

b

f

j

 

c

g

k

 

d

h

l

 

得到密文:aeimbfjcgkdhl

加密是,以行优先,来生产数组(fence为分组数),那么从一个字符的位置加上fence的就等于密文中下一个字符的位置,例如pos(a)+4=pos(e)。所有加密算法大致如下:

string Crypt::doFenceEncrypt(string text)

{

//auther:cssalp&csalp

      //strreplace(text," ","*");

      text=strnospace(text);

      string ret="";

      int i=0,j=0;

      int len=text.length();

      int step=fenceNum;

      for(i=0;i<fenceNum;i++)

      {

           j=i;

           while(j<len)

           {

                 ret+=text.at(j);

                 j+=fenceNum;

           }

      }

      //strreplace(ret,"*"," ");

      return ret;

}

 

2、            栅栏解密

栅栏解密相对要复杂些。在前面我们可以看到,加密是会产生一些空白,而这些空白在生产密文是并没有记录,所以这就造成了解密的复杂度。

我们以密文:aeimbfjcgkdhl为例

 

a

e

i

m

b

f

j

 

c

g

k

 

d

h

l

 

这里要定义一些变量,以方便讲解:

Len

密文长度(这里是13)

Column

Colum(这里是4)

Fence(row)

分组数(这里是4)

Space_num

空格数,也代表了有空格的行数

 

我们发现,a、e、i都可以通过通过移动column位找到相邻的下一个字符,而从b开始所有字符都可以通过移动column-1位找到相邻的下一个字符。但是对于m,必须提升考虑,因为如果m移动column为,本来应该为空的,应该结束的。但是在密文中为m,移动column位,是字符c(因为比没有标记空格的原因)。

针对这样的情况,可以按如下的方法处理。

首先找到startpos(在这里为b的位置),

如果当前位置>startpos,那么移动column-1

如果是最后一行,并且当前位置>startpos那么结束

如果当前位置<startpos,那么移动column

Startpos=(fence-space_num)*col+1;

Space_num=fence-(len%fence)

string Crypt::doFenceDecrypt(string fence)

{

string ret="";

      int len=fence.length();

      int spaceNum=(fenceNum-(len%fenceNum))%fenceNum;//number of space of last column l

      int col=0;

      if(spaceNum==0)

      {

           col=len/fenceNum;

      }else{

           col=len/fenceNum+1;

      }

      int startpos=(fenceNum-spaceNum)*col;//should+1,ê?but for computor,ê? it's ok!

      int step=col;

      int i=0,j=0;

      for(i=0;i<col;i++)

      {

           //read column by column

           j=i;

           while(j<len)

           {

                 ret+=fence.at(j);

                 if(j>=startpos)

                 {

                      j+=(step-1);

                 }else{

                      j+=step;

                 }

 

                 if((i==(col-1))&&j>startpos)

                 {

                      //last colum and step over the startpos,then break;

                      break;

                 }

           }

      }

      return  ret;

}

 

 

 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
栅栏密码是一种简单的加密方式,其原理是将明文按照一定长度分成若干个小段,然后将这些小段排列成一个矩阵,再按照一定顺序读取矩阵中的元素即可得到密文。解密时只需要将密文按照相同的顺序排列成矩阵,再按照顺序读取矩阵中的元素即可得到明文。 以下是 Java 实现栅栏密码的加密解密的示例代码: ```java public class RailFenceCipher { // 加密 public static String encrypt(String plaintext, int rails) { int len = plaintext.length(); char[][] fence = new char[rails][len]; for (int i = 0; i < rails; i++) { for (int j = 0; j < len; j++) { fence[i][j] = '.'; } } int rail = 0, dir = 1; for (int i = 0; i < len; i++) { fence[rail][i] = plaintext.charAt(i); rail += dir; if (rail == 0 || rail == rails - 1) { dir = -dir; } } StringBuilder ciphertext = new StringBuilder(); for (int i = 0; i < rails; i++) { for (int j = 0; j < len; j++) { if (fence[i][j] != '.') { ciphertext.append(fence[i][j]); } } } return ciphertext.toString(); } // 解密 public static String decrypt(String ciphertext, int rails) { int len = ciphertext.length(); char[][] fence = new char[rails][len]; for (int i = 0; i < rails; i++) { for (int j = 0; j < len; j++) { fence[i][j] = '.'; } } int rail = 0, dir = 1; for (int i = 0; i < len; i++) { fence[rail][i] = '*'; rail += dir; if (rail == 0 || rail == rails - 1) { dir = -dir; } } int idx = 0; for (int i = 0; i < rails; i++) { for (int j = 0; j < len; j++) { if (fence[i][j] == '*' && idx < len) { fence[i][j] = ciphertext.charAt(idx++); } } } StringBuilder plaintext = new StringBuilder(); rail = 0; dir = 1; for (int i = 0; i < len; i++) { plaintext.append(fence[rail][i]); rail += dir; if (rail == 0 || rail == rails - 1) { dir = -dir; } } return plaintext.toString(); } public static void main(String[] args) { String plaintext = "HELLO WORLD"; int rails = 3; String ciphertext = encrypt(plaintext, rails); String decrypted = decrypt(ciphertext, rails); System.out.println("Plaintext: " + plaintext); System.out.println("Ciphertext: " + ciphertext); System.out.println("Decrypted: " + decrypted); } } ``` 输出结果: ``` Plaintext: HELLO WORLD Ciphertext: HORELWRLLDO Decrypted: HELLO WORLD ``` 在上面的示例代码中,encrypt() 方法实现栅栏密码的加密,decrypt() 方法实现栅栏密码的解密,main() 方法演示了如何使用这两个方法加密解密字符串。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值