-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplayfair.py
91 lines (63 loc) · 7.25 KB
/
playfair.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
### Hacky code for solving playfair ciphers (6x6). Substitutes in plaintext pairs from known bits of grid. Unknown pairs are left as CIPHERTEXT
### Decoding Rules:
### Same row/column => letters below
### Rectangle/ => opposite corner, same row (standard Playfair)
### Also outputs csv with frequencies of each pair
import numpy as np
import collections
import csv
#Enter text
text = "6WINFVHJU2ONTIA2P256WLHP5845RDQD89HP5CFNRFYVCOVP6WVXONUPOF89HPPVOVVJVP3PEYAWPWY8RDNPE5CPAVFN75W6AWBYJR2U4B56VZVOYP6WINFVRZEYP00PWLHP5845RDQD89EYOAAU96UY2BHRPW0EN3RFYVCOC2ZVZHWPHYITHP6AOGQD2UOSCOAWNFAWIEBDMPKDV5F98OHPJR8448HYWVBYRHFROVE5TNAVJOYOHZNFNHVP98WVW6YBAR0EBVDR54O8CWUYQDHPOVFVTMZH89BYVJP0UV0PYBARRJN6NF2BWLHB5VAWOVTNPMC5BWVPIHFNNFAWHZAMPMYDVONFAW0PLEN3VF5CACMPN3H3GO560EBVDR56AW2EVO2B75HPFV75MPYPA6AWVAOEEYN3RZHZ5C89ONPMPWCRPMZRC24BPC56HZTNYURBZHAM5CACYPC5DR2UYXRANOVD5UEY0BC5VO2THFAMACTETNPWUAIETMW62H56IWIADRHPJRDYFNOH89EYAW2TYNARBXVP0EBVDRAUFNRAWPDEMBTMPWDRCKQDDROCHNFNE0YUO8VJ8456AWPWPMFVIE45IELCDRACHPPW8995VOCWNFVAHWYOPMWRAUN6R895WK2CRDQDRFUYPURYZHHFAMACN6RJLEVON3RJE5CTYBZHPDB2BYRH86JH8OCHFNXHWEHWBYCORFOJSA8O0EYBARYPRFHYBY6AJADRBAPWUPOANZBYRBRDHNOV58A396QIVOPWOVIEAFKVV5VDOCHNFNEYSOEYAWOVDEO82BVAVPOFBVPMTN89YOHZVOP0JRACHPOCLE8OWPVD58PZVPW6NADRIKPZVP0EBVDR56CK6AWNRPVOIVYCUPW6W62PE50PU5YPVPVIEWVFYPCKHPOVHPOUYAQOACYDHPDPDLDPCKTN56ZHYPVA6AIAHPOVHZFRNP456AC06759TMMTVF89HPAVAUUPBVRA2PXYFVHPPWUAVOCPIE2CQDENOD0PTBPUPYVPCUE246VOBWPYVPCARCU5NZAVAYNPE5ENOD0PTBPURPVF56H2U2EDRBVAN3VF5C95PCMPCTWLHPOU98VOFP6WAYACHPAMAVXYVAHZNPWHAY98V2HPPCEDPGAR5898YVYAQONPOEFVYBQDCAUY4POVDRDKAW6AP0ZRDRBXVPNEHZP3AY89DR98V2PWY8A6IVFRHZVPUPMPIQ64RBDVPUYAQO6AW6BD2PYDQDZVYPVFAUVPVO6AWNVPAN5U6ANPE5HPKCVOPWFVYBSAMTAVU5BYJRRAEDUYCAHWHPPWEYSOEYAWOVNZOVAUE2AV98VIACITIEAEAVYBARYPKUOVH4AYOVITVZTHMP45OFWERJARNOHPOVHP6A98VIPUVPRO5UKIRDUFBWVP48UAO8PZNPULAIZV84OV6AWYYPBV6ACKRFUYPUZO8OIKAI6ABWVPRN8O75BWYOPMFVH3RNBYPHNPWPC2UAONPUVP98HYWVPWPVOCOF89HPPWYH6WBYY8ANBYPHRBFAAU96UY2BHROHERYWDRCXNZBYP4AYOVCPR8AWHPOCOP84FVJORAHTOUARBWVPYOIN563VYDHPHPJR48UAVIE2FV6NONRDQDEYNOTY2BHRYPVFAUNPULOWIEC5YATMWT5895RAV2EYFEP0V5YPEYVOVA2CFVHPACE0KDPUNPUBEY0BCPIAVAITHPFRAURPVFOD2CHZVPIEHWO82PASPWY8AF6AWN56BHRBPZVPTR6WEDU5N3HZA2EYV2EDRBVANFAWAQAYMPWXOCVZHWRBQAPDMPHPJR48UAV2ZVYH5CODAPYWCAVAE5SAO8LURPVFUAYAQOYPVFOE59P22PYDQDHPAMKUE04B5898YV98WVCAOFUAYDBDMPUKHYEYOYSAMTAVU5ITHZ56BHPH67DRBKFRBYY8AFDRRFUYPURNVPVOUADEHDFVZHNP45BYZVDRIKYVPDB2BYRH898O5UFNWBBO2P0EYBU5IERA2CDEAWRFUYP0HZ8O3VDR8OCAHYPRPM48YVA6YBARHZAY56HPOVHP5CPWRAYBC5DEAN56A398NIYPUPBDBHVP0UNPHN56VOIADRDQ8ORPNDUAONAC8YQDBYHPOV56VOHPFRAUBYRBRAYVIKE5OAC5HWTNAYEY0BVF58YVDE46TY2BHRDRUPV2RFAZON96VOTNB2AU56VOCAWYDEUPBWPYVPOH5EAVYBAR89IESA2BBUHPOUYATMBWYVRDYBAFUP6WDRYP6N5648ANBYPHNPHN5648HWVPRNEY0BCTB2W6YAH2WYHWVPYOAYRD0ECK48JRARACITRCP2AVU56AWXVOAC89IEYVVFHPOVOCNFOYQFDRTNPWUAIAYDHPEYYH5E562BQDHP5CEDRBVANFAWHPOCNY8OOGQDRJUB6ACPWYA3OJUVBH6AJNE2PUC2FVC248N3RJTBPUEIARRCVD58YVIKE5OAC5HWRFOJLEAVWYQDW6QDOVUAON56BD1BYCBHR8OS59ZVDRBX89EDPUVPYHVHNPWLYBC5NZVPRDWB85FAPYVZBYZVCTHN5CZVWH5EOVRYPMBWPYVPUPLEWPYBARYPVOE5P0EYOF5UVOHNVPVOUADEAOFVNP45CAHZDRRN5CZVHNVPVOUADEADRAWBFRAYBYRPVHOYQF89WYVJEROVRN5U6ARAYBHPFNCPAVHPKCVOPWFVZB8RYPIHDRBXRBHFO8CFBUYPBYVJARBMZVY8APOV56WLHPPV56HY89CPEWHRTNOVAU56VO6NACITHPPUVTAWOV89HP59P03HHPPWINCR58YV0EBVDRFVUAONPMGOPUVPVZANRPVFVPPWVOMPFNFVHPPU8OVOHW89C5BHN6UPHYNPUBONE5RJZHN6WIAYHWPOEYBQO8GENFAWARYPHPPC0PCANZRBBVINCR58YVCKVANOYPOFEYHOAYOVJRDRWYVOBUCTYBN2VORJHZYTMP6AWU64PDMP89BV6AXYQDHPDRJQ98VOE5HIVHUAP0RFHZ6ABNVCTBACITHPFRAURPCTB2WLHP57RAT0ACCKAVPD2BQDEYV2EDRBVAF9O8LUVPPMCAOF89IQAM570EHP5CPWYUVFVU2BW6AWRT46YBPWPOEYBQYPDPDLDPCK6AB0ERPMEDPUNPXPRAT0ACCKIAFVRAHTPMARBXEYHJVHJRAVYHZVUPBWA2EYQIAVOVPWY8HDRHRPVFTNAYAVHT598O56NZFVWPAWVPVODR0EN3RFYVCOBYVF5CV38OPUNPA6ALOH84OYPWPU86GERAT0ACCKHPPWHPOV56VOPYVPOFMPN3VJPMPCNOUPWNRPNPE5YHAICAHWVP46HPUAON58RDHF5678PZVPRBAWVCPWVP0EYBUY6ANZRPVFYAQONPJNVUNPRDSAMTAVU5AR2UWVBMKC58QIAM5EOVFVWPAW2UVTHJ6AWX58QIPCA2P2AUPVENFVYBBDBCVUPHP256OAOSE2DRWY6DPDEYWLHP54RZBVP2KIR8E3PWVP0EYBDE3HHVIWCKVANOBD2T6ABWVPVOON5C6AR8HPOVIH6ABVFV89MPONRDQDDRTNYURPYV48UAOFONFVYBBDBD0PUPHWN6BYDRBXVPYPVURPOJAWDOYPHP6NHP5CDRYP2B95VOMPFNDRIKYVOSFYAVIAV26AZPEDTMYBFVOSE2YHDRBYRNNPSOYPRFVHOV48DRHNFVAMPUVP48UAO8ASAUPM5UYHYUP02T48UAVOBW5UPAP2KICOHZFRRBVAP0YXPHAR0EOYVAOFIFYVVAZR6ABWAYONHWVP0EN6ZOO8LUVPO8GERFYV8ODKRDNFYBARN6F9EYAWACYP4BOWHPFVE0OVP2OCAFEICOHRYPAV2BBQUPA6AWYPN6OA6AWN56VOHPPMYXPHRPZV57AM54OVNZRPVFIFTYYBHZ87AM54HPPME04BBY6ABWYVRDQDFNHPKCAVOVPW8OHJKCDRYPHVOA48UAOYQDHPAVKUZHWPCKDREYNI5EPM84C5HWC2ZVYBN3VZ56VO2CAWOVYPR8WEBDBHVP0EBVDRFVONFCZVYPVA46HY896AAV8O2EZVAVUPHOOYVFYDHPEYHREYNY8O76BDBHVPDEMBTMPWY8AFDRHPAU8O0BYATMBNENAV8YLEEDHTVHRAYDYBHZC2598OC5YPOJRDFP6AJNWPAWFNYW5VH0GOPUVP0EBVDRFVUAON5C8OWP0PAWHPPUC2AUB2MBE2598OR8WERJHPFN98V2PUFRUPABAYSAO82UEYN2O8MPNZBYPHNPYBV0DRIWEYCVHZ98VOE5HI56MPHYYPHPFRAURP2CBQWLWP75R8YV4BEDOCHWVP2BBQHPEYVFYDHPEYWHAUC5LCOVRFYV2CN3RJARYDBD0BCO6AJNAYB2BC6ARYADRAU5HWNZRPVF2BE5V3OWCPNFE5WTR8YVU5FNPMFVNZ8O798OP02BZH48UAHYVP0EBVDRPVFNCPAVWVPDMPYPUPBDMTHZVPEZHVVO89EYO8QI6AJRPWY8RDAFUP6WUACVHZIEHWDRV5YPCTB2WYZP8OEYOFPME5RFVAW6WOWPYBC5DYJRRTEYP0MPE5OR98HYWVOCHWNPUBVYUYP0YAQO"
#Enter known values of grid. Unknown values entered as ""
grid = np.array([["P", "E", "A", "K", "O", "F"], ["H", "V", "N", "Q", "R", "S"], ["T", "U", "W", "X", "Y", "Z"], ["B", "C", "D", "G", "I", "J"], ["L", "M", "0", "1", "2", "3"], ["4", "5", "6", "7", "8", "9"]])
paired_text = []
converted_letters = []
n = 2
for index in range(0, len(text), n):
paired_text.append(text[index : index + n])
frequencies = collections.Counter(paired_text).most_common()
with open("PlayfairPairFrequencies.csv", "w") as f:
csv_writer = csv.writer(f)
for tuple in frequencies:
csv_writer.writerow(tuple)
def findbelow(first_index, second_index):
new_first_row = (first_index[0] + 1) % 6
new_second_row = (second_index[0] + 1) % 6
new_first_letter = grid[new_first_row, first_index[1]]
new_second_letter = grid[new_second_row, second_index[1]]
return new_first_letter[0] + new_second_letter[0]
def findrectangle(first_index, second_index):
new_first_letter = grid[first_index[0], second_index[1]]
new_second_letter = grid[second_index[0], first_index[1]]
return new_first_letter[0] + new_second_letter[0]
for i, tuple in enumerate(frequencies):
pair = list(tuple[0])
first_letter = pair[0]
second_letter = pair[1]
first_index = np.where(grid == first_letter)
second_index = np.where(grid == second_letter)
if len(first_index[0] == 1) and len(first_index[1] ==1) and len(second_index[0] ==1) and len(second_index[1] == 1):
if first_index[0] == second_index[0] or first_index[1] == second_index[1]:
new_letters = findbelow(first_index, second_index)
else:
new_letters = findrectangle(first_index, second_index)
if len(new_letters) == 2:
converted_letters.append(new_letters)
else:
converted_letters.append(tuple[0])
else:
converted_letters.append(tuple[0])
newtext = ""
i = 0
while i < len(text):
pair = text[i] + text[i+1]
for j, tuple in enumerate(frequencies):
if pair == tuple[0]:
new_pair = converted_letters[j]
if pair == new_pair:
newtext += new_pair
else:
newtext += new_pair.lower()
i += 2
with open("PlayfairOutput.txt", "w") as f:
f.write(newtext)