Given the matrix , use a Hill cipher to decipher the enciphered text using modulo 26, where , , , .
Which one of the 5 choices below is the deciphered message?
.
Write a general program(in any language) to decipher a Hill cipher given the enciphered text and a square matrix.
The program should not contain any predefined functions or procedures. That is you must create all functions and procedures and they should appear in the program, and not called from a library you created.
Note: For the program
Refer to previous problem. . .
This program is a slight modification of the program I wrote in the previous problem.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
I wrote this program in Free Pascal.
program HillCipher_todecipher; {self contained for brillant}
const maxnum = 30;
type matrix = array[1 .. maxnum,1 .. maxnum + 1] of longint;
var a,b,p,holdp,holdb,y,holda,newa:matrix;
v,n,l,bool,r,m:integer;
PROCEDURE CONVERT_NUMTOTEXT(NUM:LONGINT; VAR LETTER:CHAR);
BEGIN
CASE NUM OF
0:LETTER:= 'A';
1:LETTER:= 'B';
2:LETTER:= 'C';
3:LETTER:= 'D';
4:LETTER:= 'E';
5:LETTER:= 'F';
6:LETTER:= 'G';
7:LETTER:= 'H';
8:LETTER:= 'I';
9:LETTER:= 'J';
10:LETTER:= 'K';
11:LETTER:= 'L';
12:LETTER:= 'M';
13:LETTER:= 'N';
14:LETTER:= 'O';
15:LETTER:= 'P';
16:LETTER:= 'Q';
17:LETTER:= 'R';
18:LETTER:= 'S';
19:LETTER:= 'T';
20:LETTER:= 'U';
21:LETTER:= 'V';
22:LETTER:= 'W';
23:LETTER:= 'X';
24:LETTER:= 'Y';
25:LETTER:= 'Z';
END;
END;
PROCEDURE CONVERT_TEXTTONUM(LETTER:CHAR; VAR NUM:LONGINT);
BEGIN
CASE UPCASE(LETTER) OF
'A':NUM:= 0;
'B':NUM:= 1;
'C':NUM:= 2;
'D':NUM:= 3;
'E':NUM:= 4;
'F':NUM:= 5;
'G':NUM:= 6;
'H':NUM:= 7;
'I':NUM:= 8;
'J':NUM:= 9;
'K':NUM:= 10;
'L':NUM:= 11;
'M':NUM:= 12;
'N':NUM:= 13;
'O':NUM:= 14;
'P':NUM:= 15;
'Q':NUM:= 16;
'R':NUM:= 17;
'S':NUM:= 18;
'T':NUM:= 19;
'U':NUM:= 20;
'V':NUM:= 21;
'W':NUM:= 22;
'X':NUM:= 23;
'Y':NUM:= 24;
'Z':NUM:= 25;
END;
END;
function prime(p:integer):boolean;
var n:integer;
PROCEDURE GET NUMEQS NUMBLOCKS(VAR NUMEQS,NUMBLOCKS:INTEGER);
VAR K:INTEGER;
BEGIN
IF PRIME(NUMCHARS) THEN
BEGIN
NUMEQS:= NUMCHARS;
NUMBLOCKS:= 1;
END
ELSE
BEGIN
FOR K:= 2 TO (NUMCHARS - 1) DO
BEGIN
IF NUMCHARS MOD K = 0 THEN
NUMEQS:= NUMCHARS DIV K;
END;
BOOL:= TRUE;
K:= 1;
WHILE BOOL DO
BEGIN
K:= K + 1;
IF NUMCHARS MOD K = 0 THEN
BEGIN
NUMBLOCKS:= NUMCHARS DIV K; {FOR SMALLEST FACTOR}
BOOL:= FALSE;
END;
END;
END;
END;
PROCEDURE INITDATA;
VAR HOLDSTR:STRING;
BEGIN
writeln('Enter Enciphered Message, leave no blanks');
readln(holdstr);
writeln;
NUMCHARS:= LENGTH(HOLDSTR);
GET NUMEQS NUMBLOCKS(NUMLINES,NUMBLOCKS);
FOR J:= 1 TO NUMBLOCKS DO
BEGIN
FOR K:= 1 TO NUMLINES DO
BEGIN
CONVERT_TEXTTONUM(HOLDSTR[(J - 1) * NUMLINES + K],HOLDP[K,J]);
END;
END;
writeln('Enter moduli');
readln(m);
END;
function gcf(m,k:LONGINT):LONGINT;
var n,factor,min:longint;
begin{gcf}
if m <= k then
min:= m
else min:= k;
for n:= 1 to min do
begin{loop}
if (k mod n = 0) and (m mod n = 0) then
end;{loop}
gcf:= factor;
end;{gcf}
PROCEDURE INITDATA1A;
VAR J,K:INTEGER;
BEGIN
FOR J:= 1 TO NUMLINES DO
begin
writeln('Enter row', j,' of Matrix');
FOR K:= 1 TO NUMLINES DO
begin
read(a[j,k]);
end;
writeln;
end;
for k:= 1 to numlines do
begin
for j:= 1 to numlines do
begin
holda[k,j]:= a[k,j];
end;
end;
end;
procedure matrixmult(a,b:matrix; var summat:matrix);
var j,k,s:integer;
begin{matrixmult}
for j:= 1 to NUMLINES do
begin{j}
for k:= 1 to 1 do
begin{k}
for s:= 1 to NUMLINES do
begin{s}
end;{s}
end;{k}
end;{j}
end;{matrixmult}
procedure hold(VAR C:REALMATRIX; A:MATRIX);
var k,j:integer;
begin
for k:= 1 to numlines do
begin
for j:= 1 to numlines do
begin
c[k,j]:= a[k,j];
end;
end;
end;
procedure switch2(var c:realmatrix; l,p,n:integer);
var m:integer;
begin{switch}
for m:= 1 to n do
begin{m}
end;{m}
end;{switch}
procedure safeguard2(var c:realmatrix; l:integer; var p:integer; n:integer; var v:integer; var product:real);
var m:integer;
begin{safeguard}
v:=0;
if (c[l,l] = 0) then
begin{then}
v:= 1;
m:= l;
while ((m + 1) <= n) and (v = 1) do
begin{loop}
if c[m + 1,l] <> 0 then
begin{then}
end;{then}
m:= m + 1;
end;{loop}
end;{then}
end;{safeguard}
procedure operation1(var a:realmatrix; l,n:integer; VAR PRODUCT:REAL);
var k,m:integer;
procedure operation2(var a:realmatrix; l,n:integer);
var k,m,q:integer;
FUNCTION DETERMINANT(a:realmatrix; n:integer; PRODUCT:REAL):integer;
var j,m:integer;
begin{DETERMINANT}
DIAGONAL:= 1;
FOR j:= 1 TO N DO
BEGIN{LOOP}
DIAGONAL:= DIAGONAL * (a[j,j]);
END;{LOOP}
IF DIAGONAL = 1 THEN
DET:= 1/PRODUCT
ELSE
DET:= 0;
DETERMINANT:= ROUND(DET);
END;{DETERMINANT}
procedure switch(var c:matrix; l,p,n:integer);
var m:integer;
begin{switch}
for m:= 1 to n + 1 do
begin{m}
end;{m}
end;{switch}
procedure safeguard(var c:matrix; l:integer; var p:integer; n:integer; var v:integer);
var j:integer;
begin{safeguard}
v:= 0;
if (c[l,l] mod m = 0) or (gcf(c[l,l],m) <> 1) then
begin{then}
v:= 1;
j:= l;
while ((j + 1) <= n) and (v = 1) do
begin{loop}
if (c[j + 1,l] mod m <> 0) and (gcf(c[j + 1,l],m) = 1) then
begin{then}
end;{then}
j:= j + 1;
end;{loop}
end;{then}
end;{safeguard}
procedure operation11(var a:matrix; l,n:integer);
var j,k,i,inverse:longint;
begin{op1}
for i:= 0 to m - 1 do
begin
if (a[l,l] * i) mod m = 1 then
begin
inverse:= i;
end;
end;
for j:= 1 to n + 1 do
begin
s[l,j]:= (a[l,j] * inverse) mod m;
if s[l,j] < 0 then
s[l,j]:= m + s[l,j];
end;
for j:= 1 to n + 1 do
begin{j}
a[l,j]:= s[l,j];
end;{j}
for k:= 1 to n do
begin
for j:= 1 to n + 1 do
begin
a[k,j]:= a[k,j] mod m;
if a[k,j] < 0 then
a[k,j]:= m + a[k,j];
end;
end;
end;{op1}
procedure operation21(var a:matrix; l,n:integer);
var q,j,k,x:longint;
begin{op2}
for q:= 1 to n do
begin{q}
if q <> l then
begin{then}
x:= m - a[q,l];
for j:= 1 to n + 1 do
begin{j}
s[q,j]:= (x * a[l,j] + a[q,j]);
end;{j}
for j:= 1 to n + 1 do
begin{j}
a[q,j]:= s[q,j];
end;{j}
end;{then}
end;{q}
for k:= 1 to n do
begin
for j:= 1 to n + 1 do
begin
a[k,j]:= a[k,j] mod m;
if a[k,j] < 0 then
a[k,j]:= m + a[k,j];
end;
end;
end;{op2}
procedure onesol(var a:matrix; n,r:integer);
var j,K:integer;
begin
strsum:= '';
for j:= 1 to n do
begin
X[J,J]:= A[J,N + 1] MOD M;
Y[J,R]:= X[J,J];
IF X[J,J] < 0 THEN
BEGIN
X[J,J]:= M + X[J,J];
Y[J,R]:= X[J,J];
END;
end;
FOR K:= 1 TO N DO
BEGIN
STR(X[K,K],STRBkk);
STRSUM:= STRSUM + STRBkk + ' ';
END;
end;
PROCEDURE DECIPHER;
VAR J,K,T,N:INTEGER;
BEGIN
WRITELN(' DECIPHERED BLOCKS');
WRITELN(' -----------------');
FOR J:= 1 TO NUMBLOCKS DO
BEGIN
FOR K:= 1 TO NUMLINES DO
BEGIN
A[K,NUMLINES + 1]:= HOLDP[K,J];
END;
for l:= 1 to numlines do
begin{l}
safeguard(a,l,r,numlines,v);
if v = 0 then
begin{then}
operation11(a,l,numlines);
operation21(a,l,numlines);
end;{then}
end;{l}
ONESOL(A,NUMLINES,J);
WRITELN(' ',STRSUM);
FOR T:= 1 TO NUMLINES DO
BEGIN
FOR N:= 1 TO NUMLINES DO
BEGIN
A[T,N]:= HOLDA[T,N];
END;
END;
END;
STRTEXT:= '';
FOR J:= 1 TO NUMBLOCKS DO
BEGIN
FOR K:= 1 TO NUMLINES DO
BEGIN
CONVERT_NUMTOTEXT(Y[K,J],LETTER);
STRTEXT:= STRTEXT + LETTER;
END;
END;
WRITELN(' DECIPHERED TEXT IS:');
WRITELN(' ',STRTEXT);
END;
begin
INITDATA;
INITDATA1A;
hold(C,A); {testing to see if (m,det(a)) = 1}
PRODUCT:= 1;
for l:= 1 to numlines do
begin{l}
safeguard2(c,l,r,numlines,v,PRODUCT);
if v = 0 then
begin{then}
operation1(c,l,numlines,PRODUCT);
operation2(c,l,numlines);
end;{then}
end;{l}
DET:= DETERMINANT(c,numlines,PRODUCT);
WHILE (gcf(m,abs(det)) <> 1) or (det mod m = 0) DO
BEGIN
writeln(' GCF(M,DET(A)) <> 1.REENTER MATRIX ');
INITDATA1A;
hold(C,A); {testing to see if (m,det(a)) = 1}
PRODUCT:= 1;
for l:= 1 to numlines do
begin{l}
safeguard2(c,l,r,numlines,v,PRODUCT);
if v = 0 then
begin{then}
operation1(c,l,numlines,PRODUCT);
operation2(c,l,numlines);
end;{then}
end;{l}
DET:= DETERMINANT(c,numlines,PRODUCT);
END;
DECIPHER;
readln;
end.
Running the program we obtain:
Deciphered Blocks:
2 2 4 1 0
1 3 1 4 2 2
1 9 1 4 1 2
1 4 1 7 1 7
1 4 2 2 8
1 8 1 3 1 4
1 9 0 6
1 4 1 4 3
3 0 2 4
Deciphered Text:
W E K N O W T O M O R R O W I S N O T A G O O D D A Y