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

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;

}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值