用顺时针的排序方式把字母或符号加密成一直行的字符, 而S会增加字与字之间的行距,使加密的排序不同
#include <cstring>
#include <iostream>
using namespace std;
class Codec {
private:
int W, H, S;
const char C[71] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 .,-!?()";
char M[70][70];
public:
Codec() :W(70),H(1),S(0){
for(int i=0;i<70;++i){
memset(&M[i][0],'\0',70);
}
generate();
}
Codec(int w, int h, int s) :W(w),H(h),S(s){
for(int i=0;i<70;++i){
memset(&M[i][0],'\0',70);
}
generate();
}
void generate(){
int left=0,top=0;
int right=W-1,bottom=H-1;
int l,r,b,t;
int idx=0;
int cur=0;
while(left<=right&&top<=bottom){
l=left;
while(l<=right){
if(idx==70)return;
if((cur+1)%(S+1)==0)M[top][l++]=C[idx++];
else {
M[top][l++]='\0';
}
++cur;
}
++top;
t=top;
while(t<=bottom){
if(idx==70)return;
if((cur+1)%(S+1)==0)M[t++][right]=C[idx++];
else {
M[t++][right]='\0';
}
++cur;
}
--right;
r=right;
while(r>=left){
if(idx==70)return;
if((cur+1)%(S+1)==0)M[bottom][r--]=C[idx++];
else {
M[bottom][r--]='\0';
}
++cur;
}
--bottom;
b=bottom;
while(b>=top){
if(idx==70)return;
if((cur+1)%(S+1)==0)M[b--][left]=C[idx++];
else {
M[b--][left]='\0';
}
++cur;
}
++left;
}
}
void config(int w, int h, int s) {
W=w;
H=h;
S=s;
for(int i=0;i<70;++i){
memset(&M[i][0],'\0',70);
}
generate();
}
void showSetting() {
cout<<"W="<<W<<", "<<"H="<<H<<", "<<"S="<<S<<endl;
for(int i=0;i<H;++i){
for(int j=0;j<W;++j){
if(M[i][j]=='\0')cout<<" ";
else cout<<M[i][j];
}
cout<<endl;
}
char seq[71]={0};
getSeq(seq);
cout<<"Seq: "<<seq<<endl;
}
void getSeq(char out[]){
int idx=0;
for(int i=0;i<W;++i){
for(int j=0;j<H;++j){
if(M[j][i]=='\0')continue;
out[idx++]=M[j][i];
}
}
}
void encode(char in[], char out[]) {
char seq[71]={0};
getSeq(seq);
for(int i=0;i<1000;++i){
if(in[i]=='\0')break;
bool flag=true;
for(int j=0;j<71;++j){
if(in[i]==C[j]){
out[i]=seq[j];
flag=false;
break;
}
}
if(flag)out[i]=in[i];
}
}
void decode(char in[], char out[]) {
char seq[71]={0};
getSeq(seq);
for(int i=0;i<1000;++i){
if(in[i]=='\0')break;
bool flag=true;
for(int j=0;j<71;++j){
if(in[i]==seq[j]){
out[i]=C[j];
flag=false;
break;
}
}
if(flag)out[i]=in[i];
}
}
};
int main() {
char cmd, inStr[1000], outStr[1000];
bool fin=false;
Codec C;
while(!fin) {
cout << "\nCommand: ";
cmd = cin.get();
switch(cmd) {
case 'C':
int w,h,s;
cin>>w>>h>>s;
C.config(w,h,s);
cin.ignore(1000,'\n');
break;
case 'Q':
cout << "Quit\n";
cin.ignore(1000,'\n');
fin=true;
break;
case 'S':
C.showSetting();
cin.ignore(1000,'\n');
break;
case 'E':
cin.get();
cin.getline(inStr,1000);
C.encode(inStr,outStr);
cout << outStr<<endl;
break;
case 'D':
cin.get();
cin.getline(inStr,1000);
C.decode(inStr,outStr);
cout << outStr<<endl;
break;
}
}
return 0;
}