1 #include<stdio.h> 2 3 int main(){ 4 char msg[700]; 5 int i,j,t; 6 int d=0; 7 char c; 8 printf("请在输入的字符串后加上'$'\n"); 9 while(1){//统计输入了多少个字符,以$结尾 10 c=getchar(); 11 if(c=='$')break; 12 msg[d]=c; 13 d++; 14 } 15 int times=0;//计数 16 int times2[10]={0}; 17 int chonghe(int d){ 18 float down=0.059;//阈值 19 int i,j=0; 20 for(j=2;j<10;j++){//不断尝试密钥长度 21 int a=0; 22 int t=0; 23 24 int no=0; 25 int k; 26 float sum=0.0; 27 int num[10][30]={0}; 28 char e[700]; 29 char group[10][400]; 30 for(i=0;i<d;i+=j){//分组 31 group[0][a]=msg[i]; 32 group[1][a]=msg[i+1]; 33 if(j>2&&i+2<d)group[2][a]=msg[i+2]; 34 if(j>3&&i+3<d)group[3][a]=msg[i+3]; 35 if(j>4&&i+4<d)group[4][a]=msg[i+4]; 36 if(j>5&&i+5<d)group[5][a]=msg[i+5]; 37 if(j>6&&i+6<d)group[6][a]=msg[i+6]; 38 if(j>7&&i+7<d)group[7][a]=msg[i+7]; 39 if(j>8&&i+8<d)group[8][a]=msg[i+8];//密钥最长支持为10位 40 if(j>9&&i+9<d)group[9][a]=msg[i+9]; 41 a++; 42 } 43 44 45 46 for(i=0;i<a;i++){//分组后统计一个分组里各个字母出现的次数 47 no=(int)group[0][i]-97; 48 num[0][no]++; 49 no=(int)group[1][i]-97; 50 num[1][no]++; 51 if(j>2){ 52 no=(int)group[2][i]-97; 53 num[2][no]++; 54 } 55 if(j>3){ 56 no=(int)group[3][i]-97; 57 num[3][no]++; 58 } 59 if(j>4){ 60 no=(int)group[4][i]-97; 61 num[4][no]++; 62 } 63 if(j>5){ 64 no=(int)group[5][i]-97; 65 num[5][no]++; 66 } 67 if(j>6){ 68 no=(int)group[6][i]-97; 69 num[6][no]++; 70 } 71 if(j>7){ 72 no=(int)group[7][i]-97; 73 num[7][no]++; 74 } 75 if(j>8){ 76 no=(int)group[8][i]-97; 77 num[8][no]++; 78 } 79 if(j>9){ 80 no=(int)group[9][i]-97; 81 num[9][no]++; 82 } 83 } 84 times=0; 85 86 for(t=0;t<j;t++){//计算重合指数 87 sum=0.0; 88 for(i=0;i<26;i++){ 89 sum=sum+(num[t][i]/(float)a)*(num[t][i]/(float)a); 90 } 91 if(sum<down) times+=1; 92 } 93 if(times==0)times2[j]=1;//值都满足阈值的分组记为1 94 else times2[j]=0; 95 96 int temp=0; 97 int times3=0; 98 for(i=0;i<j;i++){//判断有几组大于阈值 99 if(times2[i]==1){ 100 times3++; 101 temp=i; 102 } 103 } 104 if(times3==1&&j==9)return temp;//只有一组就反馈出来 105 else if(times3>1) { 106 down=down+0.001;//超过一组就增加阈值 107 j=0;//从头再来 108 continue; 109 } 110 else if(times3==0&&j==9){//阈值过高,从头再来 111 down=down-0.001; 112 j=0; 113 continue; 114 } 115 116 } 117 } 118 119 int temp=chonghe(d); 120 printf("密钥长度为:%d\n",temp); 121 122 void fmi(int d,int temp){//计算重合互指数,前面步骤与计算重合指数一致 123 int a=0; 124 int t=0; 125 int i=0; 126 int j=0; 127 int q=0; 128 int no=0; 129 float sum=0.0; 130 int num[10][30]={0}; 131 char group[10][400]; 132 int number[10]={0};//记录各位的偏移量 133 134 for(i=0;i<d;i=i+temp){//分组 135 group[0][a]=msg[i]; 136 group[1][a]=msg[i+1]; 137 if(temp>2&&i+2<d)group[2][a]=msg[i+2]; 138 if(temp>3&&i+3<d)group[3][a]=msg[i+3]; 139 if(temp>4&&i+4<d)group[4][a]=msg[i+4]; 140 if(temp>5&&i+5<d)group[5][a]=msg[i+5]; 141 if(temp>6&&i+6<d)group[6][a]=msg[i+6]; 142 if(temp>7&&i+7<d)group[7][a]=msg[i+7]; 143 if(temp>8&&i+8<d)group[8][a]=msg[i+8];//密钥最长支持为10位 144 if(temp>9&&i+9<d)group[9][a]=msg[i+9]; 145 a++; 146 } 147 148 for(i=0;i<a;i++){//统计一个分组里各个字母出现的次数 149 no=(int)group[0][i]-97; 150 num[0][no]++; 151 no=(int)group[1][i]-97; 152 num[1][no]++; 153 if(d>2){ 154 no=(int)group[2][i]-97; 155 num[2][no]++; 156 } 157 if(d>3){ 158 no=(int)group[3][i]-97; 159 num[3][no]++; 160 } 161 if(d>4){ 162 no=(int)group[4][i]-97; 163 num[4][no]++; 164 } 165 if(d>5){ 166 no=(int)group[5][i]-97; 167 num[5][no]++; 168 } 169 if(d>6){ 170 no=(int)group[6][i]-97; 171 num[6][no]++; 172 } 173 if(d>7){ 174 no=(int)group[7][i]-97; 175 num[7][no]++; 176 } 177 if(d>8){ 178 no=(int)group[8][i]-97; 179 num[8][no]++; 180 } 181 if(d>9){ 182 no=(int)group[9][i]-97; 183 num[9][no]++; 184 } 185 } 186 int k=0;//偏移量 187 int mark[10]={0}; 188 for(i=0;i<temp-1;i++){ 189 for(t=i+1;t<temp;t++){ 190 //printf("\n第%d组与第%d组:\n",i+1,t+1); 191 for(q=0;q<26;q++){ 192 sum=0.0; 193 for(j=0;j<26;j++){ 194 if(j-q<0)k=j-q+26; 195 else k=j-q; 196 sum=sum+(num[i][j]/(float)a)*(num[t][k]/(float)a); 197 } 198 //printf("%d:%f\t",q,sum); 199 if(sum>0.060){ 200 if(i==0) { 201 number[t]=26-q; 202 203 mark[t]=1; //标为1则表示该位有一值大于阈值 204 //break; 205 } 206 else if(i==1){ 207 if(mark[t]==0)number[t]=abs(26-q-number[1]); 208 //break; 209 } 210 } 211 } 212 213 214 } 215 } 216 for(i=1;i<temp;i++){printf(" %d",number[i]);} 217 218 int key[10]; 219 int pos_key[26][10]; 220 for(i=0;i<26;i++){ 221 printf("\n第%d个密钥:",i+1); 222 for(t=1;t<temp;t++){ 223 key[t]=i+number[t]; 224 if(key[t]>=26)key[t]=key[t]-26; 225 pos_key[i][t]=key[t]; 226 } 227 pos_key[i][0]=i; 228 for(t=0;t<temp;t++){ 229 printf("%c",pos_key[i][t]+97); 230 } 231 232 } 233 int dec; 234 for(j=0;j<26;j++){ 235 printf("\n第%d次:\n",j+1); 236 for(i=0;i<d;i+=temp){ 237 for(t=0;t<temp;t++){ 238 dec=(int)msg[i+t]-pos_key[j][t]-97; 239 if(dec<0)dec=dec+26; 240 printf("%c",(char)(dec+97)); 241 } 242 243 } 244 245 } 246 } 247 248 fmi(d,temp); 249 250 return 0; 251 252 }
代码写得有些臃肿,但是能用就行。
浙公网安备 33010602011771号