week _________6 to 12
week _________6 to 12
THEORY:
ALGORITHM
Begin
Step1: Declare array path [5] [5], min, a [5][5], index, t[5];
Step 5: i=1
Step 7: j=1
End
SOURCE CODE:
//*********************************
//*********************************
#include<stdio.h>
void main()
{
int path[5][5],i,j,min,a[5][5],p,st=1,ed=5,stp,edp,t[5],index;
for(i=1;i<=5;i++)
for(j=1;j<=5;j++)
scanf("%d",&a[i][j]);
scanf("%d",&p);
for(i=1;i<=p;i++)
for(j=1;j<=5;j++)
scanf("%d",&path[i][j]);
for(i=1;i<=p;i++)
t[i]=0;
for(j=1;j<=5;j++)
edp=path[i][j+1];
t[i]=t[i]+a[stp][edp];
if(edp==ed)
break;
else
stp=edp;
}
min=t[st];index=st;
for(i=1;i<=p;i++)
if(min>t[i])
min=t[i];
index=i;
for(i=1;i<=5;i++)
printf("--> %d",path[index][i]);
if(path[index][i]==ed)
break;
}
OUTPUT:
12345
12345
12345
12345
12345
12345
12345
minimum cost 14
week 7
AIM: Take a 64 bit playing text and encrypt the same using DES algorithm.
THEORY:
Data encryption standard was widely adopted by the industry in security products. Plain
text is
encrypted in blocks of 64 bits yielding 64 bits of cipher text. The algorithm which is
parameterized by a
56 bit key has 19 distinct stages. The first stage is a key independent transposition and
the last stage is
exactly inverse of the transposition. The remaining stages are functionally identical but
are
parameterized by different functions of the key. The algorithm has been designed to
allow decryption
ALGORITHM/FLOWCHART:
Begin
Step8: read"%d",&ch
case 1:
step12: fflush(stdin)
step13 : gets(plain)
step15: gets(key)
step16: lp=strlen(key)
step19: increment i
step23: puts(cipher)
step24: break
case 2:
step28: increment i
step29: initialize plain[i]=cipher[i]^lp
step32: puts(plain)
step33:break
case 3:
step34:exit(0);
End
SOURCE CODE:
/*Take a 64 bit playing text and encrypt the same using DES algorithm */
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
void main()
int i,ch,lp;
char cipher[50],plain[50];
char key[50];
while(1)
printf("\n-----MENU-----\n");
scanf("%d",&ch);
switch(ch)
fflush(stdin);
gets(plain);
gets(key);
lp=strlen(key);
for(i=0;plain[i]!='\0';i++)
cipher[i]=plain[i]^lp;
cipher[i]='\0';
puts(cipher);
break;
for(i=0;cipher[i]!='\0';i++)
plain[i]=cipher[i]^lp;
puts(plain);
break;
case 3: exit(0);
}
getch();
OUTPUT:
Week8:
Data encryption is an important feature in data protection. There are various methods used
to encrypt and decrypt data to enhance the safety of data transmitted.
In this article, we will look at AES as a method of data encryption and decryption.
AES, Advanced Encryption Standard is a block cipher text encryption and decryption
algorithm that processes a block of 128 bits of data using secret keys of 128, 192, or 256
bits.We will also discuss how this algorithm can be implemented using the Java
programming language.
AES is a 128-bit symmetric block ciphertext. This algorithm uses substitution and
permutations; known as the SP networks. It consists of multiple texts to produce a cipher
text. AES performs its calculations in the form of byte data instead of bit data.
This means that AES treats 128 bits of a clear text block as 16 bytes. The number of rounds
during the encryption process depends on the key size being used. For example:
Data to be encrypted is stored in a 4 by 4 matrix format called the state array. Each
output takes a state array as input and gives a similar array as output.
In a 16-bytes matrix, each cell represents 1-byte, this means that four cells which is the
equivalent of four bytes represent one word, implying that each state array has four
words.
The implementation of AES involves doing a set of simple operations repeatedly. Each
repetition is called a "round". Depending on the size of the key (128, 192 or 256 bit), the
input (block of 16 bytes) goes through 10, 12 or 14 rounds. In applying the 2 Big Ideas -
Diffusion and Confusion, AES makes sure that each bit in the 16 byte block depends on
every bit in the same block from 2 rounds previously. That's quite the achievement, so lets
speak about the operations in detail.
sourse code
In subBytes each of the 16 bytes is replaced by a byte from the S-box (a lookup table). The code would look
like:
For invSubBytes, only the lookup table is changed. The code is input[i] = invsbox[input[i]]. The values
for both lookup tables can be found on the wiki page. If this step appears really simple, its because it is.
Nevertheless, I'd suggest writing a test to check if its working correctly.
• input :=[]uint32{0x8e9ff1c6,0x4ddce1c7,0xa158d1c8,0xbc9dc1c9}
• expected :=[]uint32{0x19dba1b4,0xe386f8c6,0x326a3ee8,0x655e78dd}
Another useful test would be to apply subBytes and invSubBytes on 16 random bytes and check if you get
back the original.
In shiftRows, the rows are shifted left. The top row is left untouched, the second row by 1 byte, the third row
by 2 bytes, the fourth row by 3 bytes. As depictedbelow
• funcshiftRows(state []uint32){
• for i :=1; i <4; i++{
• // rotate word left by specified number of bytes
• state[i]=rotWordLeft(state[i], i)
• }
• }
input :=[]uint32{
0x8e9f01c6,
0x4ddc01c6,
0xa15801c6,
0xbc9d01c6}
expected :=[]uint32{
0x8e9f01c6,
0xdc01c64d,
0x01c6a158,
0xc6bc9d01}
InShift Rows is the inverse operation. The top row is left untouched and the next 3 rows are shifted right by
1, 2, 3 bytes. Again, I'd recommend writing a test to ensure that applying
both shiftRows and invShiftRows to random bytes returns the original.
This step is slightly complicated, compared to the other 3. The state is operated on column-
wise. Each byte of the column is replaced based on an operation. As you'd expect,
in invMixColumns the 4 bytes are replaced by the 4 original ones.
Speaking about the operation itself, it involves multiplication and addition in the Galois
field. That sounded arcane to me, until I realised that I can get the results of multiplication
via a lookup table and addition is just bit-wise XOR.
// r0 = 2*a0 + 3*a1 + a2 + a3
// r1 = a0 + 2*a1 + 3*a2 + a3
// r2 = a0 + a1 + 2*a2 + 3*a3
// r3 = 3*a0 + a1 + a2 + 2*a3
r0 = gMulBy2[a0]^ gMulBy3[a1]^ a2 ^ a3
r1 = a0 ^ gMulBy2[a1]^ gMulBy3[a2]^ a3
r2 = a0 ^ a1 ^ gMulBy2[a2]^ gMulBy3[a3]
r3 = gMulBy3[a0]^ a1 ^ a2 ^ gMulBy2[a3]
return
r0 = gMulBy14[a0]^gMulBy11[a1]^gMulBy13[a2]^gMulBy9[a3]
r1 = gMulBy9[a0]^gMulBy14[a1]^gMulBy11[a2]^gMulBy13[a3]
r2 = gMulBy13[a0]^gMulBy9[a1]^gMulBy14[a2]^gMulBy11[a3]
r3 = gMulBy11[a0]^gMulBy13[a1]^gMulBy9[a2]^gMulBy14[a3]
return
Each of the gMulBy lookup tables are 256 bytes in size. (You can find them here)
input :=[]uint32{
0xdbf201c6,
0x130a01c6,
0x532201c6,
0x455c01c6}
expected :=[]uint32{
0x8e9f01c6,
0x4ddc01c6,
0xa15801c6,
0xbc9d01c6}
For invMixColumns, the test vectors are simply reversed. As with the other steps, it's a
good idea to check if your mixColumns and invMixColumns invert each other.
I'm not going to explain Galois field arithmetic here for 2 reasons: I'd prefer to keep this
post short, and its not necessary to know exactly how it works whileimplementing AES. I
do recommend reading this book by the creators of AES if you're interested in that or other
interesting topics like cryptanalysis of AES.
Step 4: addRoundKey
The simplest of all the steps. A bit-wise XOR between the 16-byte state and the appropriate 16-bytes of the
expanded key.
As you probably know, XOR-ing any input with the same key twice returns the original input. That's why
we use the same operation with the same key in both encryption and decryption.
Potential gotcha
Be careful of how you fill the state matrix with your 16 bytes of input.
// wrong
0123
4567
891011
12131415
// correct
04812
15913
261014
371115
EXPERIMENT NO: 9
AIM: Using RSA algorithm encrypt a text data and Decrypt the same.
THEORY:
RSA method is based on some principles from number theory. In encryption process
divide the
plain text into blocks, so that each plain text message p falls in the interval 0<p<n this can
be done by
grouping the plain text into blocks of k bits. Where k is the largest integer for which 2
power k <n is
true. The security of this method is based on the difficulty of factoring large numbers. The
encryption
ALGORITHM/FLOWCHART:
Step1: Start
Step14: break
Step15: if ’ (flag==0) ‘
Step25: read m
Step26: Intialize x=strlen(m)
Step28: write"\nSource\t->----------------------------------<-destination\n"
Step30:
write"\n***********************************************************\n"
Step31: write"\n"
Step34: Increment i
Step36: write"\t%d",m[i]-97
Step45: write
"\n***********************************************************\n"
Step 47 end
SOURCE CODE:
/*Using RSA algorithm encrypt a text data and Decrypt the same*/
#include<stdio.h>
#include<ctype.h>
#include<math.h>
#include<string.h>
void main()
int a,b,i,j,t,x,n,k=0,flag=0,prime[100];
char m[20],pp[20];
float p[20],c[20];
double e,d;
for(i=0;i<50;i++)
flag=0;
for(j=2;j<i/2;j++)
if(i%j==0)
flag=1;
break;
if(flag==0)
prime[k++]=i;
a=prime[k-1];
b=prime[k-2];
n=a*b;
t=(a-1)*(b-1);
e=(double)prime[2];
d=1/(float)e;
printf("\nKey of encryption is:%lf\n",d);
scanf("%s",&m);
x=strlen(m);
printf("\nSource\t->----------------------------------<-destination\n");
printf("\nChar\tnumeric\tcipher\t\tnumeric\t\tchar \n");
printf("\n***********************************************************\n");
printf("\n");
for(i=0;i<x;i++)
printf("%c",m[i]);
printf("\t%d",m[i]-97);
c[i]=pow(m[i]-97,(float)e);
c[i]=fmod(c[i],(float)n);
printf("\t%f",c[i]);
p[i]=pow(c[i],(float)d);
p[i]=fmod(p[i],(float)n);
printf("\t%f",p[i]);
pp[i]=p[i]+97;
printf("\t%c\n",pp[i]);
printf("\n***********************************************************\n");
printf("\n");
OUTPUT:
WEEK – 10
AIM:
To study about Socket Programming and Client - Server model under UNIX operating
systems.
DESCRIPTION:
Connection-oriented service
In Internet Protocol terminology, the basic unit of data transfer is a datagram. This
is basically a header followed by some data. The datagram socket is connectionless.
2.A single socket can send and receive packets from many different computers.
3.Best effort delivery.4.Some packets may be lost some packets may arrive out of order.
1.Is a connection-oriented.
1. Socket creation:
protocol: Protocol value for Internet Protocol(IP), which is 0. This is the same number
which appears on protocol field in the IP header of a packet.(man protocols for more
details)
2. Setsockopt: This helps in manipulating options for the socket referred by the file
descriptor sockfd. This is completely optional, but it helps in reuse of address and port.
Prevents error such as: “address already in use”.
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
3. Bind:
After creation of the socket, bind function binds the socket to the address and port
number specified in addr(custom data structure). In the example code, we bind the server
to the localhost, hence we use INADDR_ANY to specify the IP address.
4. Listen:
It puts the server socket in a passive mode, where it waits for the client to approach the
server to make a connection. The backlog, defines the maximum length to which the
queue of pending connections for sockfd may grow. If a connection request arrives when
the queue is full, the client may receive an error with an indication of
ECONNREFUSED.
5. Accept:
It extracts the first connection request on the queue of pending connections for the
listening socket, sockfd, creates a new connected socket, and returns a new file descriptor
referring to that socket. At this point, connection is established between client and server,
and they are ready to transfer data.
Implementation
Here we are exchanging one hello message between server and client to demonstrate
the client/server model.
Server.c
// programming
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
structsockaddr_in address;
intopt = 1;
intaddrlen = sizeof(address);
charbuffer[1024] = { 0 };
== 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
if(setsockopt(server_fd, SOL_SOCKET,
sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if(bind(server_fd, (structsockaddr*)&address,
sizeof(address))
< 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if(listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
if((new_socket
= accept(server_fd, (structsockaddr*)&address,
(socklen_t*)&addrlen))
< 0) {
perror("accept");
exit(EXIT_FAILURE);
printf("%s\n", buffer);
close(new_socket);
shutdown(server_fd, SHUT_RDWR);
return0;
client.c
// programming
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
structsockaddr_in serv_addr;
charbuffer[1024] = { 0 };
return-1;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// form
<= 0) {
printf(
return-1;
if((client_fd
= connect(sock, (structsockaddr*)&serv_addr,
sizeof(serv_addr)))
< 0) {
printf("\nConnection Failed \n");
return-1;
printf("%s\n", buffer);
close(client_fd);
return0;
Compiling:
Output:
Week11: Write a socket program (usingc)for interaction between server and client processes
using Unix Domain sockets.
client1.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(void)
char buffer[256];
if(socket_fd < 0)
printf("socket() failed\n");
return 1;
}
/* start with a clean address structure */
address.sun_family = AF_UNIX;
printf("connect() failed\n");
return 1;
buffer[nbytes] = 0;
close(socket_fd);
return 0;
server1.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
{
int n bytes;
char buffer[256];
buffer[nbytes] = 0;
close(connection_fd);
return 0;
int main(void)
socklen_t address_length;
pid_t child;
if(socket_fd < 0)
printf("socket() failed\n");
return 1;
unlink("./demo_socket");
* start with a clean address structure */
address.sun_family = AF_UNIX;
printf("bind() failed\n");
return 1;
if(listen(socket_fd, 5) != 0)
printf("listen() failed\n");
return 1;
child = fork();
if(child == 0)
{
/* now inside newly created connection handling process */
return connection_handler(connection_fd);
close(connection_fd);
close(socket_fd);
unlink("./demo_socket");
return 0;
}
Experiment – 12
Week12: Write a socket program(using c)for interaction between server and client processes using
Internet Domain sockets.
Socket Creation The socket() call creates a socket, s = socket(domain, type, protocol); in
the specified domain and of the specified type. If the protocol is unspecified (a value of
0), the system selects a protocol that supports the requested socket type. The socket handle
(a file descriptor) is returned. The domain is specified by one of the constants defined in .
For the UNIX domain the constant is AF_UNIX. For the Internet domain it is AF_INET.
Constants named AF_ specify the address format to use in interpreting names. Socket
types are defined in . SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW is supported
by AF_INET and AF_UNIX. The following creates a stream socket in the Internet
domain: s = socket(AF_INET, SOCK_STREAM, 0); This call results in a stream socket
with the TCP protocol providing the underlying communication. A datagram socket for
intramachine use is created by: s = socket(AF_UNIX, SOCK_DGRAM, 0);
Binding Local Names A socket is created with no name. A remote process has no way to
refer to a socket until an address is bound to it. Communicating processes are connected
through addresses. In the Internet domain, a connection is composed of local and remote
addresses, and local and remote ports. In the UNIX domain, a connection is composed of
(usually) one or two path names. In most domains, connections must be unique.
In the Internet domain, there may never be duplicate ordered sets, such as: . UNIX domain
sockets need not always be bound to a name, but when bound there may never be duplicate
ordered sets such as: . The path names may not refer to existing files. The bind() call
allows a process to specify the local address of the socket. This forms the set (or ) while
connect() and accept() complete a socket’s association. The bind() system call is used as
follows: bind (s, name, namelen); s is the socket handle. The bound name is a byte string
that is interpreted by the supporting protocol(s). Internet domain names contain an Internet
address and port number. UNIX domain names contain a path name and a family. Code
Example 2-1 binds the name /tmp/foo to a UNIX domain socket. Code Example 2-1 Bind
Name to Socket #include ... struct sockaddr_un addr; ... strcpy(addr.sun_path, "/tmp/foo");
addr.sun_family = AF_UNIX; bind (s, (struct sockaddr *) &addr, strlen(addr.sun_path) +
sizeof (addr.sun_family)); Note that in determining the size of an AF_UNIX socket
address, null bytes are not counted, which is why strlen() use is fine. The file name referred
to in addr.sun_path is created as a socket in the system file name space. The caller must
have write permission in the directory where addr.sun_path is created. The file should be
deleted by the caller when it is no longer needed. AF_UNIX sockets can be deleted with
unlink(). Binding an Internet address is more complicated. The call is similar:
#include #include
...
...
...
fromlen = sizeof(from);
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
int main() {
int server_socket, new_socket;
struct sockaddr_in server_addr, client_addr;
int opt = 1;
int addrlen = sizeof(server_addr);
char buffer[BUFFER_SIZE] = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (listen(server_socket, 3) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
close(new_socket);
close(server_socket);
return 0;
}
// client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
int main() {
int client_socket;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE] = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
close(client_socket);
return 0;
}