I had been stuck on the playfair encoder. I could encode the letter pairs if they were in the same column/row, but the rectangle case failed. Side note: I changed the letters to numbers in my 5x5 alphabet grid and plaintext/message. So I had num(ber)[i] and num[i + 1] as, for example, the first two letters in my plaintext.
My first approach was to find the mod 5 (I think that’s how I write it?) of num[i] and num[i+1] to try and reduce them down to their “base” value in row 1. By which I mean, all of the values above row 1 were just the latter but + 5 * (row # - 1). For example, in position 1 of row 1, we have the base value of 1. To get to the # in position 1 of row 2, you just add 5 ( 1+5 = 6). From these “bases,” I was hoping to subtract them to find the shift amount (how much to add/subtract from num[i] and num[i+1] to slide them along their rows in the rectangle. I got the idea because if you have the numbers (in a pair) 2 and 9 to encrypt, you can reduce 9 to its “base” of 4 by doing 9 % 5. Then, you can subtract 4-2 to find 2 = the shift amount, which is true. We do, to encrypt, shift 2 by 2 to the right to get 4, and shift 9 by 2 to the left to get 7. Then I used if statements to determine which way to shift each number. However, not only was my logic dubious for that, I also forgot that 5 % 5 is not 5; it’s 0. So that thwarted my idea because with the case of 6,5 to encode, for example, when you reduce the numbers, you get 1 and 0. Then by subtracting them, you get the “shift” of 1, but this is obviously wrong, because the numbers actually shift 4.
[1 2 3 4 5]
[6 7 8 9 10]
My next approach was to try and find some math formula to reduce all of the numbers to their “bases” by using (approximately what I had) num[i] - 5 * Math.floor(num[i]/5). The general idea was to essentially subtract num[i] down to its base by using the floor function to find how many times to do so. That ended up failing, as if num[i] = 5, then the floor of num[i]/5 = 1, making you subtract 5 - 5 to get to 0 when in fact there should have been no subtraction; 5 was already at its base and didn’t need to be changed.
Finally I gave up trying to make some formula and just used some while loops of num[i] - 5 * x > 5. As long as this was true, then num[i] would not be in its base value form. I kept increasing x until it was; for example, if I had 16, x would initially = 0, and I would end up running the loop until x = 3 and num[i] - 5x = 1.
Then, I replaced num[i] with num[i+1] % 5 UNLESS it equaled 0, in which case I substituted 5. This essentially represents num[i+1]’s x-coord in the 5x5 grid (the 5 positions of 1-5 are shown most clearly in row 1). Since the rectangle rule slides num[i] right/left until it is below num[i+1] (its initial position) or, in other words, at the other corner of the rectangle (and the same is true for the shifting of num[i+1]), we can think of it as num[1] and num[i+1] swapping x-coords (which are their base values). Thus, by using num[i+1] % 5 or using 5 as num[i]’s new, shifted x-coord, we have shown this “rectangle.” Then I used the stored info of x to get this base value/new x-coord of num[i] back to its actual value by adding + 5x. I used a 2nd variable, y, to do the same for num[i+1].
Ex:
We want to encode “AG.” A = 1, G = 7. So: num[i] = 1 and num[i+1] = 7.
On the 5x5 grid, 1 and 7 form a square/rectangle:
[1 2 …]
[6 7 …]
To reduce num[i] (1) and num[i+1] (7) to their bases:
num[i] - 5 * x > 5 note: for num[i+1], sub y for x; x and y start at 0
1 - 50 is not greater than 5, so x remains equal to 0.
1 - 51 is not greater than 5, so y = 1 and 7’s base value = 2
num[i] and num[i+1] swap bases.
So: num[i] is 2 and num[i+1] is 1.
Then add 5x to num[i], which remains 2. 5y + 1 gives num[i+1] = 6.
Encoded #s: 2, 6 -> convert to letters: bf.
Hopefully this made some sense! I am very glad I got the playfair figured out. Sorry about the length of this.