# Bifid -- Place crib by dragging it & seeking position free of conflicts. # by ANCHISES, 2008. #------------------------------------------------------------------------- # .....paste ciphertext and crib here.... # end with a backslash wnen crib continues on next line T="LCNLYUH ENFRPUD NRKEWMI RIMVBTS RPRQAAE NRQRXML IGKDTZW ALGGDCP BOVALWP \ NRKAYYE BRFLOCN ORKVTAW WRRVETE LNNIBTF ROLATED OLRSDWA NVBITQL TGLVOWZ \ WCPFYZC RPFQMGZ" C="exegeticinsight" #crib must be lowercase. period=7 # insert period here #--------------------------------------------------------------------------- len_cipher=len(T) len_crib=len(C) def make_arrays(T,C,len_cipher,len_crib): #.....remove spaces...... t=-1 for j in range (len_crib): if C[j] != ' ': t+=1 pt[t] = C[j] t=-1 for j in range (len_cipher): if T[j] != ' ': t+=1 ct[t] = T[j] len_cipher=t+1 return(pt,ct,len_cipher) def make_ribbons(pt,ct,len_cipher,pos): #.......find leadin and leadout........ leadin=pos%period leadout=period-(pos+len_crib)%period if(leadout==period): leadout=0 #...extend crib to include dots for li and lo.... t=-1 for j in range(leadin): t=t+1 crib_new[t]='.' for j in range(len_crib): t=t+1 x=ord(pt[j])-32 crib_new[t]=chr(x) # upper case for j in range(leadout): t=t+1 crib_new[t]='.' len_new=t+1 #...truncate crib_new if final period is short..... end=pos+len_crib+leadout-1 if(end>len_cipher): len_new=len_new - (end-len_cipher) -1 #...make crib ribbon..... for j in range(0,len_new,period): block=period if(pos+j+period>len_cipher): block=len_cipher%period t=j+j-1; for k in range(block): if(crib_new[j+k]=='.'): t=t+1 ribp[t]='.' ribp[block+t]='.' else: t=t+1 ribp[t]=crib_new[j+k] x=ord(crib_new[j+k])+32 ribp[t+block]=chr(x) len_rib=len_new+len_new #...make cipher ribbon..... start=pos-leadin; t=-1 for j in range(start,start+len_new,1): t=t+1; ribc[t]=ct[j] t=t+1; x=ord(ct[j])+32 ribc[t]=chr(x) return (ribp,ribc,len_rib) #.......START............ code=['A']*500 crib=['A']*100 crib_new = ['A']*100 pt=['.']*500; ct=[0]*1000 len_new=0; nol=0 j=0;k=0;y=0 ribp=['A']*500; ribc=['.']*500 x=30 line=['A']*x; liner=['A']*x; linec=['A']*x pos=0 for j in range(x): line[j]=['A']*x for k in range (x): line[j][k]=['A']*x for j in range(20): liner[j]=['A']*20 for k in range(20): liner[j][k]=['A']*40 for j in range(20): linec[j]=['A']*20 for k in range(20): linec[j][k]=['A']*40 lol = [None]*20 lolr = [None]*20 lolc = [None]*20 pt,ct,len_cipher=make_arrays(T,C,len_cipher,len_crib) #make pt[] & ct[] print"lencipher=",len_cipher,"lencrib",len_crib," period=",period for pos in range(len_cipher-len_crib+1): nol=0; ribp,ribc,len_rib=make_ribbons(pt,ct,len_cipher,pos) #make rib_p[] & rib_c[] #....create lines........ for j in range(20): lol[j]=lolr[j]=lolc[j]=0 nol=-1;end=0 while end<1: nol=nol+1 #...find 1st match... t=-1 for j in range (len_rib): if (ribp[j] != '.' and ribc[j]!= '.'): break t=t+1; line[nol][t]=ribp[j]; ribp[j]='.' t=t+1; line[nol][t]=ribc[j]; ribc[j]='.' lol[nol]=2; add=1 #...seek all other matches in this line..... while add>0: add=0 # flag for adding a match for j in range(len_rib): if(ribp[j]!='.' and ribc[j]!='.'): flag=0 for m in range(lol[nol]): if(line[nol][m]==ribp[j] or line[nol][m]==ribc[j]): #match bad=0 for m in range(lol[nol]): if(ribp[j]==line[nol][m]): bad=1; break # ribp already in line if (bad==0): t=t+1; line[nol][t]=ribp[j] lol[nol]=lol[nol]+1; add=1 ribp[j]='.';bad=0 for m in range(lol[nol]): if(ribc[j]==line[nol][m]): bad=1; break if(bad==0): t=t+1; line[nol][t]=ribc[j] lol[nol]=lol[nol]+1; add=1 ribc[j]='.' end=1 for m in range(len_rib): if(ribp[m]>='A'): end=0; break #....divide each line into rows and columns.... for j in range(nol+1): lolr[j]=lolc[j]=0 t=-1 for j in range(nol+1): #....rows..... for k in range(lol[j]): if(line[j][k]<='Z'): bad=0 for m in range(lolr[j]): if(liner[j][m]==line[j][k]): bad=1; break if(bad==0): liner[j][lolr[j]] = line[j][k] lolr[j]=lolr[j]+1 #....columns..... for k in range(lol[j]): if(line[j][k]>'Z'): bad=0 for m in range(lolc[j]): if(linec[j][m]==line[j][k]): bad=1; break if(bad==0): linec[j][lolc[j]]=line[j][k] lolc[j]=lolc[j]+1 #....check for excess letters in row or column... bad=0 for m in range(nol+1): if(lolr[m]>5 or lolc[m]>5): bad=1; break #...check for 2 letters in same row and column... if (bad==0): for j in range(nol+1): for k in range(nol+1): flag=0 for p in range(lolr[j]): for q in range(lolc[k]): x=ord(linec[k][q])-32; if(liner[j][p]==chr(x)): flag=flag+1 if(flag>1): bad=1 if(bad==0): print "SOLUTION WITHOUT CONFLICT" print "bad=",bad," pos=",pos,"Number of lines=",nol+1 for j in range(nol+1): for k in range(lolr[j]): print liner[j][k], for k in range(5-lolr[j]): print " ", print" : ", for k in range(lolc[j]): print linec[j][k], print print print "End of program"; print