You are on page 1of 22

EXPERIMENT NO:1

OBJECTIVE-: WAP in C/C++ to encrypt and decrypt a plain text


using substitution cipher(caeser method)

THEORY & CONCEPT-: In cryptography, a Caesar cipher, also


known as a Caesar's cipher, the shift cipher, Caesar's code or
Caesar shift, is one of the simplest and most widely known encryption
techniques. It is a type of substitution cipher in which each letter in the
plaintext is replaced by a letter some fixed number of positions down
the alphabet. For example, with a shift of 3, A would be replaced by D,
B would become E, and so on. The method is named after Julius Caesar,
who used it to communicate with his generals.

METHOD OF ENCRYPTION-: The transformation can be represented


by aligning two alphabets; the cipher alphabet is the plain alphabet
rotated left or right by some number of positions. For instance, here is
a Caesar cipher using a left rotation of three places (the shift
parameter, here 3, is used as the key): Plain:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Cipher: DEFGHIJKLMNOPQRSTUVWXYZABC

To encrypt a message, simply look up each letter of the message in


the "plain" line and write down the corresponding letter in the "cipher"
line. To decipher, do the reverse.
Plaintext: the quick brown fox jumps over the lazy dog
Ciphertext: WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ
The encryption can also be represented using modular arithmetic by
first transforming the letters into numbers, according to the scheme, A
= 0, B = 1,..., Z = 25. Encryption of a letter x by a shift n can be
described mathematically as,
Decryption is performed similarly,
The replacement remains the same throughout the message, so the
cipher is classed as a type of monoalphabetic substitution, as opposed
to polyalphabetic substitution.

IMPLEMENTATION IN C/C++-:

Program : Encryption/Decryption using Caesar Cipher */

#include <iostream.h>
#include <conio.h>
#include <ctype.h>
int SQR(int x)
{
int yes=0, i=1;
while(i<=17 && yes==0)
{
if(i*i==x)
{
yes=1;
sr=i;
}
else
i++;
}
return yes;
}

void main()
{
clrscr();
int choice, n;
cout<<"CAESAR CIPHER \n";
cout<<"1. Code your text \n";
cout<<"2. Decode a cipher \n";
cin>>choice;
char A[300], W;
switch (choice)
{
case 1:
clrscr();
do
{
cout<<"Enter the total number of letters in your message (perfect
square) ";
cin>>n;
} while(SQR(n)==0);
cout<<"Enter your message : \n";
for(int o=0; o<n; o++)
{
do
{
cin>>A[o];
} while (isalnum(A[o])==0);
}
int z=0;
clrscr();
for(int y=1; y<=2*sr; y+=2)
{
for(int q=1; q<=sr; q++)
{
gotoxy(y, q);
cout<<(char)toupper(A[z]);
z++;
}
cout<<endl;
}
cout<<"\nOR\nThe coded text is \n";
for(int qw=0; qw<sr; qw++)
{
for(int c=0; c<n; c+=sr)
cout<<(char)toupper(A[c+qw]);
}
break;

case 2:
clrscr();
do
{
cout<<"Enter the number of characters in your code ";
cin>>n;
} while(SQR(n)==0);
cout<<"Enter the cipher text as it appears in rows \n";
for(int b=0; b<n; b++)
{
cin>>A[b];
cout<<"\nThe decoded text is \n";
for(int h=0; h<sr; h++)
{
for(int c=0; c<n; c+=sr)
cout<<A[c+h];
} }
break;
}

getch();
}

EXPERIMENT NO:2

OBJECTIVE-: WAP in C/C++ to encrypt and decrypt a plain text


using substitution cipher(normal method)

THEORY & CONCEPT-: In cryptography, a Caesar cipher, also


known as a Caesar's cipher, the shift cipher, Caesar's code or
Caesar shift, is one of the simplest and most widely known encryption
techniques. It is a type of substitution cipher in which each letter in the
plaintext is replaced by a letter some fixed number of positions down
the alphabet. For example, with a shift of 3, A would be replaced by D,
B would become E, and so on. The method is named after Julius Caesar,
who used it to communicate with his generals.Later this method was
advanced with the key being taken greater than 3 and this method is
called normal substitution method.

METHOD OF ENCRYPTION-: The method of encyrption is exactly the


same way as we have done in experiment no:1, but the only difference
is that the key is user input (instead of 3). According to the key the
cipher is formed and then decrypted at the receiver end.

IMPLEMENTATION IN C/C++-:

#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<process.h>
void main()
{
int ch=1,n=0,key;
char str[20];
clrscr();
printf("enter key to be used\n");
scanf("%d",&key);
key=key%26;
do
{
printf("enter 1 for encryption\n");
printf("enter 2 for decryption\n");
printf("enter 0 for exit\n");
scanf("%d",&ch);
if(ch==1)
{
n=0;
printf("enter text to be encrypted");
fflush(stdin);
scanf("%s",&str);
while(str[n]!='\0')
{
if(str[n]>=65&&str[n]<=90)
{
if((str[n]+32+key)>122)
{
str[n]=str[n]+32+key-122+96;
}
else
{
str[n]=str[n]+32+key;
}

n++;
}
puts(str);
}
if(ch==2)
{
n=0;
printf("enter text to be decrypted"); }
fflush(stdin);
scanf("%s",&str);
while(str[n]!='\0')
{
if(str[n]>=97&&str[n]<=122)
{
if((str[n]-(32+key))<65)
{
str[n]=str[n]-(32+key)+26;
}
else
{
str[n]=str[n]-(32+key);
}
}
n++;
}
puts(str);
}
}

while(ch!=0);
getch();
}

EXPERIMENT NO:3

OBJECTIVE-: -: WAP in C/C++ to encrypt and decrypt a plain


text using transposition cipher method.

THEORY & CONCEPT-:Transposition ciphers are rarely encountered


nowadays. They differ from both code systems and substitution
ciphers; in a transposition cipher the letters of the plaintext are shifted
about to form the cryptogram. This can be done in a number of ways
and some systems exist where even whole words are transposed,
rather than individual letters. To encrypt Chinese, for instance, one can
use a transposition cipher operating on the individual signs of written
Chinese (using a substitution cipher for a language like Chinese would
be awkward if not impossible).

METHOD OF ENCRYPTION-: One of the easiest ways to achieve


transposition is the Single Columnar Transposition Cipher. To use it,
one needs a keyword or phrase, whose letters are numbered according
to their presence in the alphabet. The keyword Ozymandias is
numbered in the following way:

O Z Y M A N D I A S
7 10 9 5 1 6 3 4 2 8
That is, the first occurance of the letter A is numbered 1, the second 2.
There are no B:s or C:s so the next letter to be numbered are the D
followed by I, and so on.
Next the plaintext is written in rows under the numbered keyword,
one letter under each letter of the keyword. Let's say that the plaintext
to be encrypted is Company has reached primary goal. It will look like
this:
O Z Y M A N D I A S
7 10 9 5 1 6 3 4 2 8
c o m p a n y h a s
r e a c h e d p r i
m a r y g o a l
Now the letters of the plaintext are copied down by reading them off
columnwise in the order stated by the enumeration of the keyword.
The result is the finished cryptogram, which - of course - are put into
groups of five letters, like this:

AHGAR YDAHP LPCYN EOCRM SIMAR OEA


To decrypt a received message enciphered by this method, one first
must calculate the number of letters present in the cryptogram. This is
done to see how many letters there originally were in the last row. As
can be seen above, the two last columns - the ones numbered 2 and 8
- only contains two letters and this is important. Now the cryptogram
above contains 28 letters and as a legitimate user of the crypto
system, one knows that the keyword is ten letters wide. Therefore the
last row must consist of eight letters only, the two final positions being
empty. Keeping that in mind - or better still, marking the two final
position of row three in some way to indicate that they shouldn't be
used - one numbers the keyword letters (just as when encrypting) and
then start by writing the first three letters of the cryptogram under
keyword letter number one, thus:

O Z Y M A N D I A S
7 10 9 5 1 6 3 4 2 8
. . . . a . . . . .
. . . . h . . . . .
. . . . g . . . * *
Next comes column number two. Since the last position in column two
is marked by a star and shouldn't be used, one only writes the next
two letters, instead of three. Continue in the same way by writing the
next three letters under keyword letter number three, and so on up to
keyword letter eight, it will look like this:
O Z Y M A N D I A S
7 10 9 5 1 6 3 4 2 8
c . . p a n y h a .
r . . c h e d p r .
m . . y g o a l * *
Now column eight follows, and there only two letters should be written
as stated above (the position marked by a star being left empty). This
leaves six letters of the cryptogram, and these - of course - are written
in column nine and ten, and then the cleartext can be read in the
normal way, row by row.
Usually when employing a transposition cipher like the above, one
adds dummy letters to make the final group five letters long if it isn't
already full. It is important to do this before transposing the letters,
otherwise the receiver can't calculate the columns that haven't a full
number of letters if the last row isn't complete. In some cases the last
row is always made complete by adding dummy letters, but that
reduces the security of the cipher and isn't recommended (now, this
cipher is quite easy to break anyway...).

IMPLEMENTATION IN C/C++-:
#include <iostream>
void main(void)
{
char strOriginalIput[100], strPass[35], strENCR[100], outpass[100];
int istrLen = 0;
int iArray[20] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
};
cout << "\n Enter String(without space) : ";
cin >> strOriginalIput;
istrLen = strlen(strOriginalIput);
strOriginalIput[istrLen + 1] = '\0';
cout << "\n Enter Crypt Pass: ";
cin >> strPass;
int iLen = strlen(strPass);
strPass[iLen + 1] = '\0';
strcpy(outpass, strPass);
outpass[iLen + 1] = '\0';
int cnt = 0;
//cout << strOriginalIput << "\n";
for (int i = 0; i < iLen - 1; i++)
{
for (int j = 0; j < iLen - 1 - i; j++)
{
if (strPass[j + 1] < strPass[j])
{
/* compare the two neighbors */
char tmp = strPass[j]; /* swap a[j] and a[j+1] */
strPass[j] = strPass[j + 1];
strPass[j + 1] = tmp;
int t = iArray[j];
iArray[j] = iArray[j + 1];
iArray[j + 1] = t;
}
}
}
cnt = 0;
for (int z = 0; z < iLen; z++)
{
for (int x = 0; x <= iLen; x++)
{
if ((iArray[z] + iLen * x) <= istrLen)
{
strENCR[cnt++] = strOriginalIput[(iArray[z] + iLen * x) - 1];
}
}
}
strENCR[istrLen] = '\0'; //cout << strENCR << "\n\n" ;
// Output
int nl = 1;
for (i = 0; i < iLen; i++)
{
cout << outpass[i] << " ";
cout << "\n-------------------------------";
cout << "\n";
for (i = 0; i < istrLen; i++)
{
if (i == iLen * nl)
{
cout << "\n" << strOriginalIput[i] << " ";
nl++;
}
else
cout << strOriginalIput[i] << " ";
}
cout << "\n\n" << "Encrypted String : " << strENCR;
// Encryption is over, now going for decryption
cout << "\n";
char strtmp[100];
cnt = 0;
for (z = 0; z < iLen; z++)
{
for (int x = 0; x <= iLen; x++)
{
if ((iArray[z] + iLen * x) <= (istrLen))
strtmp[iArray[z] + (iLen * x) - 1] = strENCR[cnt+
+];
}
}
strtmp[istrLen] = '\0';
cout << "Decrypted String :" << strtmp << "\n\n";
}
}
EXPERIMENT NO:4

OBJECTIVE-: WAP in C/C++ to implement DLL framing method


by character stuffing.

THEORY & CONCEPT-:

• Also referred to as character stuffing.

• ASCII characters are used as framing delimiters


(e.g. DLE STX and DLE ETX)

• The problem occurs when these character patterns occur within the
“transparent” data.

Solution: sender stuffs an extra DLE into the data stream just before each occurrence of
an “accidental” DLE in the data stream.

The data link layer on the receiving end unstuffs the DLE before giving the data to the
network

IMPLEMENTATION IN C/C++-:

#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char flag='F',p='*',esc='E';
char string[100],ch;
int l,i,j=1;
FILE *fp;
clrscr();
fp=fopen("flames","w");
printf("please enter the string");
gets(string);
l=strlen(string);
printf("%c %c",flag,string[0]);
putc(flag,fp);
putc(string[0],fp);
for(i=1;i<l;i++)
{
if(j==6)
{
printf("%c\n%c",flag,flag);
putc(flag,fp);
putc(flag,fp);
j=0;
}
if(string[i]=='*'||string[i]=='F'||string[i]=='E')
{
printf("%c",esc);
putc(esc,fp);
j++;
}
if(j!=6)
{

printf("%c",string[i]);
putc(string[i],fp);
j++;
}
}
for(i=j;i<6;i++)
{
printf("%c",p);
putc(p,fp);
}
printf("F");
fclose(fp);
printf("do u want to read file (Y/N):");
ch=getche();
if(ch=='y'||ch=='Y')
{
return;
}
j=0;
printf("\n");
fp=fopen("frames","r");
ch=getc(fp);
while(ch!=EOF)
{
if(ch==esc&&j==0)
{
ch=getc(fp);
j=1;
continue;
}
if(ch==flag&&j==0)
{
ch=getc(fp);
continue;
}
if(ch==p&&j==0)
{
ch=getc(fp);
continue;
}
if(ch==flag||ch==p||ch==esc&&j==1)
{
printf("%c",ch);
j=0;
ch=getc(fp);
continue;
}
else
{
printf("%c",ch);
ch=getc(fp);
continue;

}
}

getch();
}

EXPERIMENT NO:5

OBJECTIVE-: WAP in C/C++ to implement DLL framing method


by bit stuffing.

THEORY & CONCEPT-:


• Each frame begins and ends with a special bit pattern called a flag
byte [01111110].
• Whenever sender data link layer encounters five consecutive ones in
the data stream, it
automatically stuffs a 0 bit into the outgoing stream.

• When the receiver sees five consecutive incoming ones followed by a


0 bit, it automatically destuffs the 0 bit before sending the data to the
network
layer.

IMPLEMENTATION IN C/ C++-:

#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char text[100],text1[100];
int k,n,count=0,i,j,p;
clrscr();
printf("Enter text at sender end:");
gets(text);
n=strlen(text);
for(k=0;k<=n;k++)
{
text1[k]=text[k];
}
for(i=0;i<n;i++)
{
if(text[i]=='1')
count++;
if(text[i]=='0')
count=0;
if(count==5)
{
p=1+1;
for(j=n+1;j>p;j++)
{text[j]='0';}
n++;
count=0;
}
}
printf("Bit stuffed code is:");
printf("01111110");
for(k=0;k<strlen(text);k++)
printf("%c",text[k]);
printf("01111110");
printf("\n Text at reciever end:");
for(k=0;k<=n-1;k++)
{
printf("%c",text1[k]);
}
getch();
}

EXPERIMENT NO:6

OBJECTIVE-: WAP in C/C++ to implement CRC algorithm.

THEORY & CONCEPT-:


A CRC is an error-detecting code. Its computation resembles a long
division operation in which the quotient is discarded and the remainder
becomes the result, with the important distinction that the arithmetic
used is the carry-less arithmetic of a finite field. The length of the
remainder is always less than or equal to the length of the divisor,
which therefore determines how long the result can be. The definition
of a particular CRC specifies the divisor to be used, among other
things.

Although CRCs can be constructed using any finite field, all commonly
used CRCs employ the finite field GF(2), the field of two elements,
usually called 0 and 1, comfortably matching computer architecture.
The rest of this article will discuss only these binary CRCs, but the
principles are more general.

An important reason for the popularity of CRCs for detecting the


accidental alteration of data is their efficiency guarantee. Typically, an
n-bit CRC, applied to a data block of arbitrary length, will detect any
single error burst not longer than n bits (in other words, any single
alteration that spans no more than n bits of the data), and will detect a
fraction 1-2-n of all longer error bursts. Errors in both data transmission
channels and magnetic storage media tend to be distributed non-
randomly (i.e. are "bursty"), making CRCs' properties more useful than
alternative schemes such as multiple parity checks.

The simplest error-detection system, the parity bit, is in fact a trivial


CRC: it uses the two-bit-long divisor 11.

CRCs are not, by themselves, suitable for protecting against intentional


alteration of data (for example, in authentication applications for data
security), because their convenient mathematical properties make it
easy to compute the CRC adjustment required to match any given
change to the data.

METHOD-:

The mechanics of computing an n-bit binary CRC are simple. The bits
representing the input are lined up in a row, and the (n+1)-bit pattern
representing the CRC's divisor (called a "polynomial") is positioned
underneath the left-hand end of the row. Here is the first calculation
for computing a 3-bit CRC:

11010011101100 <--- Input


1011 <--- divisor (4 Bits)
--------------
01100011101100 <--- result
If the input bit above the leftmost divisor bit is 0, do nothing and move
the divisor to the right by one bit. If the input bit above the leftmost
divisor bit is 1, the divisor is exclusive-ORed into the input (in other
words, the input bit above each 1-bit in the divisor is toggled). The
divisor is then shifted one bit to the right, and the process is repeated
until the divisor reaches the right-hand end of the input row. Here is
the last calculation:
00000000001110 <--- result of multiplication calculation
1011 <--- divisor
--------------
00000000000101 <--- remainder (3 bits)
Since the leftmost divisor bit zeroed every input bit it touched, when
this process ends the only bits in the input row that can be nonzero are
the n bits at the right-hand end of the row. These n bits are the
remainder of the division step, and will also be the value of the CRC
function (unless the chosen CRC specification calls for some
postprocessing).

IMPLEMENTATION IN C/C++-:

#include<conio.h>
#include<stdio.h>
#include<process.h>
void main()
{
int msg[20],crc[20],n,i,j,p,a,rem[10],quo[10];
clrscr();
printf("Enter Mesage size");
scanf("%d",&n);
printf("Enter message in Binary");
for(i=0;i<n;i++)
{
scanf("%d",&msg[i]);
}
printf("Enter CRC Gen. size");
scanf("%d",&p);
printf("Enter crc bits in Binary");
for(i=0;i<p;i++)
{
scanf("%d",&crc[i]);
}
a=p-1;
for(i=0;i<a;i++)
{
msg[n+i]=0;
}
printf("The Code To be Sent is - ");
for(i=0;i<(n+a);i++)
{
printf("%d",msg[i]);
}
for(i=0;i<p;i++)
{
if (msg[i]==1 && crc[i]==1)
{
rem[i]=0;
}
if( msg[i]==1 && crc[i]==0)
{ rem[i]=1;
}
if(msg[i]==0 && crc[i]==1)
{
rem[i]=1;
}
if( msg[i]==1 && crc[i]==0)
{
rem[i]=0;
}
i=0;
if(rem[i]==0 && rem[i+1]== 0 && rem[i+2]==1)
{
rem[i+4]=msg[i+4];
rem[i+5]=msg[i+5];
if(crc[i]==0)
{
rem[i]=0;
}
if(crc[i]==1)
{
rem[i]=1;
}
if((rem[i+3]==1) && (crc[i+1]==0))
{
rem[i+1]=1;
}
if(rem[i+3]==1 && crc[i+1]==1)
{
rem[i+1]=0;
}
if(rem[i+3]==0 && crc[i+1]==1)
{
rem[i+1]=1;
}
if(rem[i+3]==0 && crc[i+1]==0)
{
rem[i+1]=0;
}
if(rem[i+4]==1 && crc[i+2]==0)
{
rem[i+2]=0;
}
if(rem[i+4]==1 && crc[i+2]==1)
{
rem[i+2]=0;
}
if(rem[i+4]==0 && crc[i+2]==0)
{
rem[i+2]=0;
}
if(rem[i+5]==0 && crc[i+3]==0)
{
rem[i+3]=1;
}
if(rem[i+5]==1 && crc[i+3]==1)
{
rem[i+3]=0;
}
if(rem[i+5]==0 && crc[i+3]==1)
{
rem[i+2]=1;
}
if(rem[i+5]==1 && crc[i+3]==0)
{
rem[i+3]=0;
}
if(rem[i]==0 && rem[i+1]==0 && rem[i+2]==0 && rem[i+3]==0)
{
if(crc[i]==0)
{
rem[i]=0;
}
if(crc[i]==1)
{
rem[i]=1;
}
if(crc[i+1]==0)
{
rem[i+1]=0;
}
if(crc[i+1]==1)
{
rem[i+1]=1;
}
if(crc[i+2]==0)
{
rem[i+2]=0;
}
if(crc[i+2]==1)
{
rem[i+2]=1;}
if(crc[i+3]==1)
{
rem[i+3]=0;
}
}
printf("The code to be sent is " );
for(j=0;j<n;j++)
{
printf("%d", msg[j]);
for(i=0;i<n;i++)
{
printf("%d",rem[i]);
}
}}}
getch();
}

EXPERIMENT NO:7

OBJECTIVE-: WAP in C/C++ to find the shortest route using


dijkstra algorithm.

THEORY & CONCEPT-:

The shortest path between two nodes of a graph is a sequence of


connected nodes so that the sum of the edges that inter-connect them
is minimal.

Take this graph,

There are several paths between A and E:


Path 1: A -> B -> E 20
Path 2: A -> D -> E 25
Path 3: A -> B -> D -> E 35
Path 4: A -> D -> B -> E 20

There are several things to notice here:

1. There can be more then one route between two nodes


2. The number of nodes in the route isn’t important (Path 4 has 4 nodes but is
shorter than Path 2, which has 3 nodes)
3. There can be more than one path of minimal length

Something else that should be obvious from the graph is that any path
worth considering is simple. That is, you only go through each node
once.
Unfortunately, this is not always the case. The problem appears when
you allow negative weight edges. This isn’t by itself bad. But if a loop
of negative weight appears, then there is no shortest path. Look
at this example:

Look at the path B -> E -> D -> B. This is a loop, because the starting
node is the also the end. What’s the cost? It’s 10 - 20 + 5 = -5. This
means that adding this loop to a path once lowers the cost of the path
by 5. Adding it twice would lower the cost by 2 * 5 = 10. So, whatever
shortest path you may have come up with, you can make it smaller by
going through the loop one more time. BTW there’s no problem with a
negative cost path.

The Floyd-Warshall Algorithm

This algorithm calculates the length of the shortest path between all
nodes of a graph in O(V3) time. Note that it doesn’t actually find the
paths, only their lengths.
Let’s say you have the adjacency matrix of a graph. Assuming no loop
of negative values, at this point you have the minimum distance
between any two nodes which are connected by an edge.
ABCDE
A 0 10 0 5 0
B 10 0 5 5 10
C05000
D 5 5 0 0 20
E 0 10 0 20 0
The graph is the one shown above (the first one).
The idea is to try to interspace A between any two nodes in hopes of
finding a shorter path.
ABCDE
A 0 10 0 5 0
B 10 0 5 5 10
C05000
D 5 5 0 0 20
E 0 10 0 20 0
Then try to interspace B between any two nodes:
ABCDE
A 0 10 15 5 20
B 10 0 5 5 10
C 15 5 0 10 15
D 5 5 10 0 15
E 20 10 15 15 0
Do the same for C:
ABCDE
A 0 10 15 5 20
B 10 0 5 5 10
C 15 5 0 10 15
D 5 5 10 0 15
E 20 10 15 15 0
Do the same for D:
ABCDE
A 0 10 15 5 20
B 10 0 5 5 10
C 15 5 0 10 15
D 5 5 10 0 15
E 20 10 15 15 0
And for E:
ABCDE
A 0 10 15 5 20
B 10 0 5 5 10
C 15 5 0 10 15
D 5 5 10 0 15
E 20 10 15 15 0
This is the actual algorithm:
# dist(i,j) is "best" distance so far from vertex i to vertex j

# Start with all single edge paths.


For i = 1 to n do
For j = 1 to n do
dist(i,j) = weight(i,j)

For k = 1 to n do # k is the `intermediate' vertex


For i = 1 to n do
For j = 1 to n do
if (dist(i,k) + dist(k,j) < dist(i,j)) then # shorter path?
dist(i,j) = dist(i,k) + dist(k,j)

IMPLEMENTATION OF ALGO IN C-:

include <stdio.h>

int n; /* Then number of nodes */


int dist[16][16]; /* dist[i][j] is the length of the edge between i and j if
it exists, or 0 if it does not */

void printDist() {
int i, j;
printf(" ");
for (i = 0; i < n; ++i)
printf("%4c", 'A' + i);
printf("\n");
for (i = 0; i < n; ++i) {
printf("%4c", 'A' + i);
for (j = 0; j < n; ++j)
printf("%4d", dist[i][j]);
printf("\n");
}
printf("\n");
}

/*
floyd_warshall()

after calling this function dist[i][j] will the the minimum distance
between i and j if it exists (i.e. if there's a path between i and j)
or 0, otherwise
*/
void floyd_warshall() {
int i, j, k;
for (k = 0; k < n; ++k) {
printDist();
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i][k] * dist[k][j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i][k] + dist[k][j] < dist[i][j]) ||
(dist[i][j] == 0))
dist[i][j] = dist[i][k] + dist[k][j];
}
printDist();
}

int main(int argc, char *argv[]) {


FILE *fin = fopen("dist.txt", "r");
fscanf(fin, "%d", &n);
int i, j;
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
fscanf(fin, "%d", &dist[i][j]);
fclose(fin);

floyd_warshall();

return 0;
}