📄 246-262.html
字号:
<html><head><TITLE>Learn Encryption Techniques with BASIC and C++:Polyalphabetic Substitution</TITLE>
<!-- BEGIN HEADER --><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><SCRIPT><!--function displayWindow(url, width, height) { var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes');}//--></SCRIPT></HEAD><body bgcolor="ffffff" link="#006666" alink="#006666" vlink="#006666"><P>
<CENTER><B>Learn Encryption Techniques with BASIC and C++</B>
<FONT SIZE="-2">
<BR>
<I>(Publisher: Wordware Publishing, Inc.)</I>
<BR>
Author(s): Gil Held
<BR>
ISBN: 1556225989
<BR>
Publication Date: 10/01/98
</FONT></CENTER>
<P>
<!-- Empty Reference Subhead -->
<!--ISBN=1556225989//-->
<!--TITLE=Learn Encryption Techniques with BASIC and C++//-->
<!--AUTHOR=Gilbert Held//-->
<!--PUBLISHER=Wordware Publishing, Inc.//-->
<!--CHAPTER=5//-->
<!--PAGES=246-262//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="240-245.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="262-266.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading16"></A><FONT COLOR="#000077">The POLY2.CPP Program</FONT></H4>
<P>The program POLY2.CPP, which represents the C++ language version of the POLY2.BAS program, was developed as a continuation of our strategy of providing encryption examples in both languages. Listing 5.7 includes the POLY2.CPP program listing. The actual program, as well as the executable version of the program, are located in the C directory on the CD-ROM. Concerning the executable version of the program, its filename follows the naming convention used in this book, resulting in the filename POLY2.EXE. To distinguish the executable versions of the BASIC and C++ programs from one another, it is important to remember that although they have the same filename, they are located in different directories. That is, the file POLY2.EXE located in the directory BASIC represents the executable version of the program POLY2.BAS while the file POLY2.EXE located in the C directory represents the executable version of the program POLY2.CPP.
</P>
<P><B>Listing 5.7</B> The POLY2.CPP program listing.</P>
<!-- CODE //-->
<PRE>
/*poly2.cpp
C++ code written by Jonathan Held, April 1, 1998,
using Microsoft's Visual C++ version 5.0.
*/
//standard includes
#include<iostream.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>
#include<fstream.h>
//constants we will use
const int FIVE = 5, TWENTYFIVE = 25, TWENTYSIX = 26,
TWENTYSEVEN = 27, SIXTYFIVE = 65, NINETY = 90,
NINETYTWO = 92, SIZE = 256, BIGSIZE = 1000;
//function prototypes
bool checkInput(char * &);
void createStream(char *, char []);
void createTable(char [][TWENTYSEVEN], const char [], const char []);
void display(char *);
void formatData(char []);
bool encryptText(char *, char *, const char PTEXT[],
const char [][TWENTYSEVEN], char []);
char* formCipheredMessage(const char [], const char []
[TWENTYSEVEN],
const char[], char []);
void getFileNames(char *&, char *&);
int getInputType(void);
int getKeyword(char *&);
bool getMessage(char *, char *, const char [],
const char [][TWENTYSEVEN], char []);
void groupBUFFER(ofstream, int);
void printCipherToFile(ofstream, char[]);
bool writeMatrixToFile(const char [], const char [][TWENTYSEVEN]);
char BUFFER[BIGSIZE] = {'\0'};
//----------------------------------------------------------------
//Function: main()
//Parameters: None
//Return Type: int - 0 means program terminated normally
//Purpose: Runs the main part of the program.
//----------------------------------------------------------------
int main()
{
char plaintext[TWENTYSEVEN] = {'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','Z','\0'};
char *ptext_keyword, *ctext_keyword, *infile, *outfile;
//p_stream is used to help form the alphabetic-shifted cipher
//alphabets
char p_stream[TWENTYSIX] = {'\0'};
//c_stream represented the top row of the polyalphabetic ciphertext
//matrix
char c_stream[TWENTYSIX] = {'\0'};
//table is the actual polyalphabetic ciphertext matrix
char table[TWENTYSIX][TWENTYSEVEN], message_to_cipher[SIZE];
int type_of_input;
bool success = false;
cout << "Enter plaintext keyword or keyword phrase in UPPERCASE: ";
getKeyword(ptext_keyword);
cout << "Enter ciphertext keyword or keyword phrase in UPPERCASE: ";
getKeyword(ctext_keyword);
createStream(ptext_keyword, p_stream);
createStream(ctext_keyword, c_stream);
createTable(table, plaintext, c_stream);
getFileNames(infile, outfile);
type_of_input = getInputType();
//handle file input
if (type_of_input){
success = encryptText(infile, outfile, p_stream, table,
message_to_cipher);
}
//keyboard input
else {
success = getMessage(infile, outfile, p_stream, table,
message_to_cipher);
}
//report success of operation
if (!success){
cerr << "Error: Invalid filename specified. Goodbye." << endl;
}
else {
cout << "Press return to display resulting enciphered message."
<< endl;
//get the newlines off the current input stream
cin.get();
if (type_of_input){
cin.get();
}
display(outfile);
}
writeMatrixToFile(p_stream, table);
delete [] ptext_keyword;
delete [] ctext_keyword;
return (0);
}//end main()
//----------------------------------------------------------------
//Function: checkInput()
//Parameters: input - the keyword the user entered
//Return Type: bool - true if the input string contains an error,
// false otherwise
//Purpose: Checks the user's keyword for invalid characters.
//----------------------------------------------------------------
bool checkInput(char * &input)
{
bool error = false;
int count = strlen(input);
for (int ix=0; ix<count; ix++){
int char_value = static_cast<int>(*(input+ix));
//determine if the user did not enter an uppercase character
if ((char_value < SIXTYFIVE) || (char_value > NINETY)){
error = true;
cerr << "\aYou entered an invalid keyword!" << endl << endl
<< "Re-enter keyword: ";
break;
}
}
//check for just the newline and no other characters entered
if (count == 0){
cerr << "\aYou entered an invalid keyword!" << endl << endl
<< "Re-enter keyword: ";
error = true;
}
return error;
}//end checkInput()
//----------------------------------------------------------------
//Function: createStream()
//Parameters: input - the keyword the user entered
// stream - streams used in the polyalphabetic cipher
// matrix.
//Return Type: None
//Purpose: Creates a preliminary stream that will be used in
//conjunction with the polyalphabetic cipher matrix.
//----------------------------------------------------------------
void createStream(char *input, char stream[])
{
bool used[TWENTYSIX];
int index = 0,
count = strlen(input);
//no characters are initially used
for (int ix=0; ix<TWENTYSIX; ix++){
used[ix] = false;
}
//keep track of each character used, start forming the keyword
//alphabet
for (int jx=0; jx<count; jx++){
//get each character of the input string (integer value)
int char_value = static_cast<int>(*(input+jx));
if (used[char_value-SIXTYFIVE]){
//do nothing - the character was already used
}
else {
//mark as used and add to the keyword alphabet
used[char_value-SIXTYFIVE] = true;
*(stream+index++) = static_cast<char>(char_value);
}
}
//go through the list of characters used - those which weren't
//used should be added to the keyword alphabet
for (int kx=0; kx<TWENTYSIX; kx++){
if (!(used[kx])){
*(stream+index++) = static_cast<char>(SIXTYFIVE+kx);
}
}
stream[TWENTYSIX] = '\0';
return;
}//end createStream()
//----------------------------------------------------------------
//Function: createTable()
//Parameters: tbl - the polyalphabetic ciphertext matrix we are
// creating
// PTEXT - the plaintext alphabet we use to form
// shifted keyword alphabets; starting position
// within the plaintext alphabet is determined by
// the cipher stream
// CSTREAM - the cipher stream that represents the top
// row of the polyalphabetic ciphertext matrix
//Return Type: None
//Purpose: Creates a polyalphabetic ciphertext matrix. Each character
//in the cipherstream represents a row in the polyalphabetic ciphertext
//matrix; this row is a shifted alphabet that starts at the character
//subsequent to the cstream character.
//----------------------------------------------------------------
void createTable(char tbl[][TWENTYSEVEN], const char PTEXT[],
const char CSTREAM[])
{
for (int ix=0; ix<TWENTYSIX; ix++){
int start_pos = (static_cast<int>(CSTREAM[ix]) - SIXTYFIVE + 1) %
TWENTYSIX;
for (int jx=0; jx<TWENTYSIX; jx++){
tbl[ix][jx] = PTEXT[(start_pos + jx) % TWENTYSIX];
}
tbl[ix][TWENTYSIX] = '\0';
}
return;
}//end createTable()
//----------------------------------------------------------------
//Function: display()
//Parameters: name - the name of the file the user wants displayed
//Return Type: None
//Purpose: Echoes the resulting output file to the screen.
//----------------------------------------------------------------
void display(char *name)
{
ifstream infile(name, ios::in);
char input[SIZE];
if (!(infile)){
cerr << "Unable to open input file for display." << endl;
}
else {
while (infile.getline(input, SIZE, '\n')){
cout << input << endl;
}
}
cout << endl;
return;
}//end display()
//----------------------------------------------------------------
//Function: encryptText()
//Parameters: inp_file - the name of the input plaintext file
/ outp_file - the name of the output file to save the
/ encrypted text
/ PSTREAM[] - the top row of the polyalphabetic ciphertext
/ matrix
/ TBL[][] - the polyalphabetic ciphertext matrix
/ encoded_msg[] - the message to be encoded
//Return Type: bool, indicating success of operation
//Purpose: Used to encrypt file input. Takes each line of the input
//file, encrypts it, and saves the result to the specified output
//file.
//----------------------------------------------------------------
bool encryptText(char * inp_file, char * outp_file, const char PSTREAM[],
const char TBL[][TWENTYSEVEN], char encoded_msg[])
{
bool success = false;
char ip[SIZE];
//declare file stream objects
ifstream input(inp_file, ios::in);
ofstream output(outp_file, ios::app);
if ((!input) || (!output)){
//do nothing - I/O error; user will be notified upon
//procedure's return to main()
}
else {
success = true;
while (input.getline(ip, BIGSIZE, '\n')){
//check to see if the user wants the line to appear in plaintext
if (ip[0] == '/'){
if (strlen(BUFFER)>0){
//empty whatever is in the buffer
groupBUFFER(output, strlen(BUFFER));
//adjust the buffer
strcpy(BUFFER, (BUFFER+strlen(BUFFER)));
//output plaintext
}
output << ip << endl;
}
else {
//encipher the line
char *msg = formCipheredMessage(PSTREAM, TBL, ip, encoded_msg);
//print the cipher in groups of five to the ouput file
printCipherToFile(output, msg);
}
}
//empty the rest of the buffer
groupBUFFER(output, strlen(BUFFER));
//notify user where plaintext and ciphertext files are
cout << "Plaintext file is: " << inp_file << endl;
cout << "Encrypted file is: " << outp_file << endl << endl;
}
//don't forget to close the files
input.close();
output.close();
//return success of the operation
return success;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -