Sei sulla pagina 1di 25

Encryption & Error Checking

Encryption
Encryption, what the...?

Yeah that's right, encryption, A Great Way to secure your privacy. Ok, you just got a new job
and you are now quite comfortable with it? You download a couple of tools but there is one that
catches your eye. It asks you to enter the Filename of the file you want to encrypt so you do as it
says, and pick your co-worker‟s business file, work.dat it loads for a while and then says,
encryption complete, you feel as though you could take on an army.

Two days later, your co-worker is unable to complete his job for work and loses his job, you
innocently deny the events that ruined up his data file. But deep down you feel guilty, you hate
encryption and never want to see it again.

Wrong! 'MOST' encryption programs are released with a 'decryptor'. You ARE able to turn your
co-worker‟s work back into readable format! Ok, encryption turns your files into useless code
that's unreadable, ready to continue on?

The Basic Algorithm


Ask for file1 to be encrypted.
Ask for file2 to output encrypted data too.
Encrypt file1 and save as file2, leave file1 untouched.

Example Code (general encryption)


FILE *stream1, *stream2;
if((stream1 = fopen(argv[1], "rb")) == NULL) { /*ERROR*/ }
if((stream2 = fopen(argv[2], "wb")) == NULL) { /* ERROR*/}
encrypt(file1,file2);
END C!
What was that above???
stream1 and 2 are simply pointers to of type FILE
argv[1] is the commandline parameter passed to programs in MS-Dos.
example:
program file1 file2 key
file1 is argv[1]
program is argv[0]
file2 is argv[2] and key is argv[3]

Ok so we know how to accept parameters! Or do we? Here's an example help you understand:

#include <cstdio>

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


{
printf("Parameter 1 is %s, 2 is %s.\n", argv[1], argv[2]);
printf("Program name is %s.\n", argv[0];
printf("Number of parameters: %d\n", argc);
return 0;
}

Enter the Binary

As you already know binary is the only language the computer really understands. Although you
may type some programs up and compile them, wether it be C++, asm, delphi, vb, fortran or
your neighbour‟s carrot tree, your computer does not read what you tell it to, I know it sucks, but
its the truth. All your pretty little code is converted into a jumble of 1's and 0's.

DO you remember the binary number system?


BINARY NUMBER SYSTEM:
Decimal - Binary
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
16 10000
32 100000
64 1000000
128 10000000
256 100000000

How about Logical AND

Input Output
0 0 0
0 1 0
1 0 0
1 1 1

The 'And' operator in C is '&'. & will only return 1 when both bits are 1.

Logical XOR

Input Output
0 0 0
0 1 1
1 0 1
1 1 0
One’s Complement

By applying ones compliment to the decimal number 21845 each bit in this number will be
inversed.

21845 = 10101010 1010101

Hence applying One‟s Complement we get

10101010 10101010 = 42945450

In C, we apply the ~ operator to decimal 21845

XOR is good for encryption because applying it with the old value it was XORED with turns the
bits back into their previous value:

Example-

We have two characters:


'a' and 'b'
We want to encrypt 'a' by XORing the bits of 'b' into it.
Do this:

int encrypted;
char a,b;
a = 'a';
b = 'b';

encrypted = a ^ b;

Which will yield this result:


'a' = 97 which is 01100001 in binary
'b' = 98 which is 01100010
encrypted now equals: 00000011
But were learning how to decrypt as well right? Sure are, to restore the value 'a' to its original
unencrypted state we simple XOR the encrypted value with 'b' again:

int new;
new = encrypted ^ b;
which gives us this binary number: 01100001 which is, you guesses it, 'a'!... WOW

So now we know the basic component behind the XOR encryption of characters. Continue on to
learn various other methods of encryption.

Ancient Cryptography

Back in the days of World War II and even before that, ancient methods of cryptography have
been passed down from generation to generation. The following is just a few of them:

I. ROT13 - A popular method of hiding text so that only people who actually take
the time to decode it can actually read it. You swap letters; A becomes N, and N
becomes A. It was quite popular on bulletin board systems and Usenet
newsgroups. You can do it with the cryptogram solver also, if you make A=N,
B=O, C=P, etc.

II. Caesarian Shift - Where ROT13 was based on you adding 13 to the letters, a
Caesar cipher lets you add an arbitrary value. Again, you can do it with the
cryptogram solver, but you can scroll through values of N pretty easily with this
tool.

III. Atabash - A very simplistic cipher where you change A into Z, B into Y, and so
on.
Ancient Methods in recent programming

Rot 13

What is Rot13 encryption?

Rot13 simple means rotating alphabet by 13 characters. It is a very primitive encryption method
which can be easily decrypted on knowledge. But for a non-technical user it still remains an
unsolved mystery. Rot13 encryption is very easy to understand and use. It is very similar to the
Caesar-Encryption method. Here what we do is rotate the character backwards or front by 13
characters in the ASCII table. The means "a" becomes "n" and "p" becomes "}". This method has
been used in many news delivery systems as to prevent third parties from gaining easy access to
it in the past. But now there are many better encryption systems being used which remain hard to
be decrypted. Rot13 uses very simple algorithms and the encryption/decryption functions can be
easily made.

Just below is the code that performs this operation by taking only the characters and shifts it 13
places alphabetically, while integers and any other input are left as they were. Ensure that you go
through each line carefully to understand the basic functionality of the program.

#include<stdio.h>

int ROT = 13;


int main(void)
{
int c,e;

while((c=getchar())!=EOF)
{
if(c >='A' && c <='Z')
{
if((e = c + ROT) <= 'Z')
putchar(e);
else
{
e = c - ROT;
putchar(e);
}
}
else if(c >='a' && c <='z')
{
if((e= c + ROT) <= 'z')
putchar(e);
else
{
e = c - ROT;
putchar(e);
}
}
else
putchar(c);
}

return 0;
}

putchar is a function in the C programming language that writes a single character to the
standard output stream, stdout. Now you can add the provided rot13.cpp file to a new project on
Microsoft Visual Studio and Run. You will see the command window appear (blank of course)
awaiting your message to be coded. Enter any message you like, e.g. your name, and see what
happens (WOW!)

Of course with an encoded message, the receiver would like to be able to decode it without
having to sift through each letter and rotate them by 13 places. How many letters does the
alphabet have? ___ 13 x 2 = ___ so if you rotate the encoded message characters by 13
places you should get.....(drum roll) The original message . So the decoding program is the
same as the encoding, you can see this for yourself by re-running the code and retyping the
encoded characters.

Given the code above, if you were to “copy and paste” it into Microsoft Visual Studio, it would
compile and run without errors.

So your mission is to now ask the user for an input and give the encrypted output. When this is
finished you now realize that the encryptor is a decryptor and can be used as any.

Caesarian Shift

In cryptography, a Caesar cipher, also known as a Caesarian 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.

The encryption step performed by a Caesar cipher is often incorporated as part of more complex
schemes, such as the Vigenère cipher, and still has modern application in the ROT13 system. As
with all single alphabet substitution ciphers, the Caesar cipher is easily broken and in practice
offers essentially no communication security.
This method is as simple as ROT 13 in that the algorithm that it takes to encode a message is the
simplest as can be. The code below is a clear example of this.

#include <iostream>
#include <string.h>
using namespace std;

int main()
{

char str1[80];
int i = 0;
int offset;

cout << "What do you want your password to be?\n";


cin >> str1;
cout << "What do you want your offset number to be?\n";
cin >> offset;
while(i<strlen(str1)){
str1[i] = int(str1[i]) + offset;
i++;
}

cout << str1<<endl;


return 0;
}

Since [Message + Offset = Encrypted Text]

Come up with your Caesarian Shift Decryptor. Write the program below.

______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________

Vigenère cipher

The Vigenère cipher is named for Blaise de Vigenère, although Giovan Battista Bellaso had
invented the cipher earlier. Vigenère did invent a stronger autokey cipher.The Vigenère cipher is
a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the
letters of a keyword. It is a simple form of polyalphabetic substitution.

The Vigenère cipher has been reinvented many times. The method was originally described by
Giovan Battista Bellaso in his 1553 book La cifra del. Sig. Giovan Battista Bellaso; however, the
scheme was later misattributed to Blaise de Vigenère in the 19th century, and is now widely
known as the "Vigenère cipher".

This cipher is well known because while it is easy to understand and implement, it often appears
to beginners to be unbreakable; this earned it the description le chiffre indéchiffrable (French for
'the unbreakable cipher'). Consequently, many people have tried to implement encryption
schemes that are essentially Vigenère ciphers, only to have them broken.

This type of encryption is a little more difficult to „break‟ for any average whiz-kid but still the
algorithm is simple for you to have invented it yourself if you were living in Blaise de Vigenère
days.

The code below shows a program that can encrypt a message using the Vigenère cipher method
and decrypt as well. Ensure that you go through each line and understand carefully the
functionality.

#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
int mode,crypt,i = 0,z = 0;
char text[256],key[256],key2[256];

cout << "* Vigenere Cipher *" << endl;


cout << "Encrypt(1) or Decrypt(0)?: ";
cin >> mode;
if (argc)
{
cout << "Enter text: ";
cin >> text;
cout << "Enter key: ";
cin >> key;
}

while(string(key).length() < string(text).length())


{
strcpy(key2, key);
strcat(key, key2);
}
switch(mode)
{
case 1: // Encryption
while(text[i] != '\0')
{
crypt = int(text[i]) + int(key[z]) - 150;
cout << char(crypt);
if (z > string(key).length())
{
z = 0;
}
z++;
i++;
}
cout << "\n";
break;

case 0: // Decryption
while(text[i] != '\0')
{
crypt = int(text[i]) - (int(key[z]) - 150);
cout << char(crypt);
if (z > string(key).length())
{
z = 0;
}
z++;
i++;
}
cout << "\n";
break;
default: // Error
cout << "Incorrect value.";
break;
cout << "\n";
}
system("PAUSE");
return 0;
}

See the provided Vigenere.cpp file provided and run it with Visual C++ 2008. If run into any
problems the TA will be pleased to assist you in any way they can. Write your algorithm for the
code provided above.

______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
Error Checking

Recursion Technique

This piece was extracted from


http://www.codeproject.com/KB/cpp/Recursion_Prmr_CPP_01.aspx

Introduction

In general, recursion means self repeating patterns. In Mathematics, it can be a function that is
defined in terms of itself, such as factorial, Fibonacci etc. In computer programming, recursion
means a function that is defined in terms of itself. In other words, a function that calls itself.
Every recursive function has a termination condition; otherwise, it will call itself forever, and
this condition can be called the base condition.

In C++, the types of recursion can be defined in more than one dimension. In one dimension, it
can be categorized as runtime recursion and compile time recursion using template meta-
programming.

Runtime recursion is the most common recursion technique used in C++. This can be
implemented when a C++ function (or member function) calls itself. In C++, we can also do
compile time recursion with the help of template meta-programming. When you instantiate a
template class (or structure) in C++, the compiler will create the code of that class at compile
time. Just like runtime recursion, we can instantiate the template class itself to perform the
recursion. Similarly, we also need the termination condition; otherwise, instantiation will go
forever, at least theoretically, but, of course, limited to the resources of the computer and the
compiler. In template meta-programming, we can specify the termination condition (or base
condition) with the help of template specialization or partial template specialization, depending
on the termination condition.

The other way to look at recursion is how a recursive algorithm is implemented. Recursive
algorithms can be implemented in more than one way, such as linear, tail, mutual, binary, or
nested recursion. We can implement them either at compile time using template meta-
programming, or at runtime using functions or member functions. For ECNG 2007 we will be
focusing on the runtime recursion technique.
We can represent the different types of recursion using the following diagram. This diagram
shows the different types of recursion based on their implementation (i.e., linear, tail, mutual
etc.) and when it will be performed.

Linear Recursion

Linear recursion is the simplest form of recursion, and perhaps the most commonly used. In this
recursion, a function simply calls itself until it reaches the termination condition (also known as
the base condition); this process is known as winding. After calling the termination condition, the
execution of the program returns to the caller; this is known as unwinding.

Functions may perform some additional tasks during winding or unwinding, such as in the case
of the factorial function, it will multiply the input number with the return value of the function
during the unwinding phase. This process can be demonstrated with the following diagram that
shows both the winding and unwinding phase of the factorial function using linear recursion.
Mathematically, we can write the factorial function recursively this way, i.e., when the value of
“n” is zero, then return one, and when the value of “n” is greater than zero, then call the function
recursively with “n-1” and multiply the result with the return value of the recursive function.

1n  0 
f ( n)   
n * f (n  1)n  0 

int Factorial(int no)


{
// error condition
if (no < 0)
return -1;

// termination condition
if (0 == no)
return 1;

// linear recursive call


return no * Factorial(no - 1);
}

Winding Process:
Function called Function return
Fact(6) 6*Fact(5)
Fact(5) 5*Fact(4)
Fact(4) 4*Fact(3)
Fact(3) 3* Fact(2)
Fact(2) 2* Fact(1)
Fact(1) 1* Fact(0)
Terminating Point
Fact(0) 1

Unwinding Process
Fact(1) 1*1
Fact(2) 2*1
Fact(3) 3*2*1
Fact(4) 4*3*2*1
Fact(5) 5*4*3*2*1
Fact(6) 6*5*4*3*2*1

The above program is a runtime version of linear recursion. Here, we have a termination
condition of 0, and this program starts unwinding when it reaches the termination condition.
There is one more error condition in this program to prevent infinite function calls if someone
passes a negative number to this function. This function will simply return -1 as an error if the
value of the parameter is negative.
Tail Recursion

Tail recursion is a specialized form of linear recursion where the recursive function call is
usually the last call of the function. This type of recursion is usually more efficient because a
smart compiler will automatically convert this recursion into a loop to avoid nested function
calls. Because a recursive function call is usually the last statement of a function, there isn‟t any
work done during the unwinding phase; instead, they simply return the value of the recursive
function call. Here is an example of the same program converted to tail recursion.

We can define the tail recursion mathematically using this equation, i.e., when the value of “n” is
zero, then simply return the value of “a”; if the value of “n” is greater than zero, then call the
recursive function by passing “n-a” and “n*a”. Here, you can also notice that during the
unwinding phase, every recursive function simply returns the value of “a”.

an  0
f (n, a)   
 f (n  1, n * a)n  0 

int Factorial(int no, int a)


{
// error condition
if (no < 0)
return -1;

// termination condition
if (0 == no || 1 == no)
return a;

// Tail recursive call


return Factorial(no - 1, no * a);
}

This is a modified version of the linear recursion program. Here, we perform all the calculations
before calling the recursive function, and simply return whatever value we got from the recursive
function. Here, the calculation order is the reverse of the linear recursion. In linear recursion, we
first multiply 1 with 2, then its result with 3, and so on; on the other hand, here we multiply n
with n-1, then with n-2, until we reach 0.

Tail recursion is very useful and sometimes unavoidable in functional languages, because they
might not have a looping construct. They usually perform the looping with the help of tail
recursion. You can do almost everything with tail recursion that can be done with looping, but
this is usually not true in reverse. Here is a very simple example to demonstrate looping via tail
recursion:

// implement looping via tail recursion


// simple version
void RecursiveLoop(int n)
{
// termination condition
if (0 == n)
return;

// action to be performed
cout << n << endl;

// tail recursive call


return RecursiveLoop(--n);
}
Binary Recursion

In binary recursion, the recursive function calls itself twice, not once. This type of recursion is
very useful in some data structures like traversing a tree in prefix, postfix, or infix order,
generating Fibonacci numbers etc.

Binary recursion is a specific form of exponential recursion where one function calls the
recursive function more than once (in case of binary, two). In other words, recursive functions
call exponentially in this type of recursion.

Mathematically, we can define the Fibonacci sequence as:

0n  0 
 
F (n)  1n  1 
 F (n  1)  F (n  2)n  1 
 

int Fib(int no)


{
// error condition
if (no < 1)
return -1;

// termination condition
if (1 == no || 2 == no)
return 1;

// binary recursive call


return Fib(no - 1) + Fib(no - 2);
}

Here is a simple implementation of Fibonacci numbers calling the recursive function twice. Here
we have two base cases, when the value of input parameter is 1 and 2. This is, of course, not the
best implementation of Fibonacci numbers, and we can convert it into tail recursion by changing
it a little bit.

int Fib(int n, int a, int b)


{
// termination condition
if (1 == n)
return b;
else
// tail recursive call
return Fib(n-1, b, a+b);
}

Here, we convert binary recursion into tail recursion. We simply perform the calculation before
calling any recursive function, therefore we do not need to call the recursive function twice. In
Fibonacci numbers, we always need the last two numbers, so after performing the calculation on
the last two numbers, we just discard the first one, i.e., “a”, and replace the second one in place
of the first, i.e., place the value of “b” in “a”, and calculate the next number.

Mathematically, we can define this as:

bn  1
F (n, a, b)   
 F (n  1, b, a  b)n  1
Error checking using Recursion

Here is a decent program that accepts the user input based on the type and within certain range
and acknowledges the type only to return the exact same input. Could you decipher what type of
recursion is used here?

/*
Purpose: To get an integer input from the user
Accepts: msg - display message
Min - smallest acceptable value
Max - largest acceptable value
quit - vaue to force quit on return
*/

#include <cstdlib>
#include <iostream>

using namespace std;

int getUserInput ( const char* msg , const int min , const int max , const int quit );
char getUserInput ( const char* msg , const char min , const char max , const char quit );

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


{
int t = getUserInput ( "Enter an integer" , 0 , 10 , -1 );
if ( t != -1 )
cout << " Integer entered is: " << t << endl;

char c = getUserInput ( "Enter a letter" , 'A' , 'z' , '0' );


if ( c != '0' )
cout << "Letter entered is: " << c << endl;

system("PAUSE");
return EXIT_SUCCESS;
}

int getUserInput ( const char* msg , const int min , const int max , const int quit )
{
int input;

do {
cout << msg << " (Range: " << min << " to " << max << " , quit= " << quit << "): ";
cin >> input;
} while ( input != quit && ( input < min || input > max ) );
return input;
}

/*
Purpose: To get a char input from the user
Accepts: msg - display message
Min - smallest acceptable value
Max - largest acceptable value
quit - vaue to force quit on return
*/
char getUserInput ( const char* msg , const char min , const char max , const char quit )
{
char input;

do {
cout << msg << " (Range: " << min << " to " << max << " , quit= " << quit << "): ";
cin >> input;
} while ( input != quit && ( input < min || input > max ) );
return input;
}
Could you decipher what type of recursion is used here? Explain your findings.

______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
Reviewing and Moving On

So let‟s see what we‟ve done so far.

The first type of encryption technique that we‟ve been introduced to is that of substitution
techniques. For example, the Caesar cipher which allow that we replace each letter of the
alphabet with the letter standing three places further down in the alphabet. This was the simplest
substitution cipher, and was made famous by its use by Julius Caesar. For example:

Plain: meet me after the toga party

Cipher: PHHW PH DIWHU WKH WRJD SDUWB

Note that the alphabet is wrapped around, so when we reach Z, we wrap back around to A.

Can you write a function which takes a string as its parameter and utilizes a loop to produce and
return an encrypted string. Write that function of the form:

string encrypt_caesar_loop(string toEncrypt);

Can you write an equivalent function which does the same by way of recursion?

string encrypt_caesar_recursion(string toEncrypt);

Moving right along now, another form of substitution cipher is that of the monoalphabetic
ciphers. With only 25 possible keys, the Caesar cipher discussed so far is far from secure. A
dramatic increase in the key space can be achieved by allowing an arbitrary substitution. So
instead the cipher line may be any permutation of the 26 alphabetic characters, which means that
there are 26! different possibilities, or greater than 4x1026 possible keys. This approach is known
as a monoalphabetic substitution cipher, because a single cipher alphabet (mapping from plain
alphabet to cipher alphabet) is used per message.

However, there is a line of attack. If the cryptanalyst knows the nature of the plaintext, then the
analyst can exploit the regularities of the language. For example, with English, the most used
letter is the letter „E‟ and when a single letter is used, it is usually the letter A or the letter I.
There are dedicated techniques to exploiting this in order to overcome such encryption
techniques.

How would you go about writing a function which would arbitrarily encrypt along this
technique?
Hint: You can utilize an array lookup. If we treat with the letter „a‟ being the first indexing
position, we can compute an index location within a 26 character array by subtracting „a‟ from
our letter (to get 0 offset). Think carefully what I mean by this and see if you can write functions
of the form:

char lookup_encrypted_char(char someChar);

which would lookup within an array the encrypted character and another function:

string encrypt_mono_loop(string toEncrypt)

which utilizes a loop and the array lookup function to return an encrypted string.

Another early encryption technique is known as the playfair cipher. This technique is perhaps the
best known multiple letter encryption cipher. This treats diagrams in the plaintext as single units
and translates them into ciphertext diagrams. The playfair algorithm is based on the use of 5x5
matrix of letters constructed using a keyword. Here is an example, solved by Lord Peter Wimsey
in Dorothy Sayer‟s Have His Carcase:

M O N A R

C H Y B D

E F G I/J K

L P Q S T

U V W X Z

In this case, the keyword is monarchy. The matrix is constructed by filling in the letters of the
keyword (minus duplicates) from left to right and from top to bottom, and then filling in the
remainder of the matrix with the remaining letters in alphabetic order. The letters I and J count as
one letter. Plaintext is encrypted two letters at a time according to the following rules:

1. Repeating plaintext letters that would fall in the same pair are separated with a filler
letter, such as x, so that the word balloon would be treated as: ba lx lo on
2. Plaintext letters that fall in the same row of the matrix are each replaced by the letter to
the right, with the first element of the row circularly following the last. For example, ar is
encrypted as RM.

3. Plaintext letters that fall in the same column are each replaced by the letter beneath with
the top element of the row circularly following the last. For example, mu is encrypted as
CM.

4. Otherwise, each plaintext letter is replaced by the letter that lies in its own row and the
column occupied by the other plaintext letter. Thus hs becomes BP and ea becomes IM
(or JM as the encipherer wishes).

This is a pretty simple algorithm that was thought of as being near unbreakable during WW2. It
was thus used as the standard field system by the British army during the war and still enjoyed
considerable use by the US and other Allied forces during the war.

Despite this level of confidence in its security, the Playfair cipher is relatively easy to break
because it still leaves much of the structure of the plaintext language intact. A few hundred
letters of ciphertext are generally sufficient to crack the cipher.

Can you write a function that is of the form:

string encrypt_playfair (string toEncrypt)

that would implement the above algorithm for Lord Peter Wimsey‟s solution?

What we have considered above are some simple substitution encryption techniques.

Another type of encryption technique is that of transposition. While substitution techniques


involve the substitution of a ciphertext symbol for a plaintext symbol, a very different type of
mapping is achieved by performing some sort of permutation on the plaintext letters. This
technique is known as a transposition cipher.

The simplest form of such a cipher is the rail fence technique. The plaintext is written down as a
sequence of diagonals and then read off as a sequence of rows. For example, to encipher the
message: meet me after the toga party with a rail fence of depth 2:
m e m a t r h t g p r y

e t e f e t e o a a t

And thus the encrypted message becomes:

MEMATRHTGPRYETEFETEOAAT

This sort of thing would be trivial to cryptanalyze, and thus a more complex scheme may be to
write the message in a rectangle, row by row, and read the message off, column by column, and
read the message off, column by column, but permute the order of the columns. The order of the
columns then becomes the key to the algorithm. For example:

Key: 4 3 1 2 5 6 7

A T T A C K P

O S T P O N E

D U N T I L T

W O A M X Y Z

Thus the ciphertext becomes:

TTNAAPTMTSUOAODWCOIXKNLYPETZ

Can you write a function of the following prototype that would take as a string as input and
utilize this technique as it is presented here?

string encrypt_transposition(string toEncrypt)

To conclude, the above information that is presented here considered some rather simple
encryption techniques. There are many more encryption techniques which have far superior
levels of security, and also far greater levels of difficulty to implement. However, the basic idea
here is to apply your programming techniques in order to implement the above given algorithms.
All techniques given here can be written as functions utilizing loops and recursive techniques.

Potrebbero piacerti anche