Listing 2: The Cryptor class implementation

//**************************************************************
// Copyright (c) 1998 by Warren Ward. Permission is granted to
// use this source code as long as this copyright notice appears
// in all source files that now include it.
//**************************************************************

#include    "Stream Cryptor.h"

//***********************************************
// CLASS IMPLEMENTATION
// Cryptor
//***********************************************

Cryptor::Cryptor():
    // Initialize LFSRs to non-zero values.
    m_LFSR_A( 0x13579BDF ),
    m_LFSR_B( 0x2468ACE0 ),
    m_LFSR_C( 0xFDB97531 ),

    // Initialize feedback masks to magic numbers. 
    m_Mask_A( 0x80000062 ), 
    m_Mask_B( 0x40000020 ), 
    m_Mask_C( 0x10000002 ), 

    // Set up LFSR "rotate" masks.
    m_Rot0_A( 0x7FFFFFFF ), 
    m_Rot0_B( 0x3FFFFFFF ), 
    m_Rot0_C( 0x0FFFFFFF ),
    m_Rot1_A( 0x80000000 ), 
    m_Rot1_B( 0xC0000000 ), 
    m_Rot1_C( 0xF0000000 )
    {
    }

Cryptor::~Cryptor()
    {
    }

void Cryptor::Set_Key( const std::string & Key )
    {
    int Index = 0; 

    // Set default key if none provided.
    m_Key = Key;
    std::string         Seed    = m_Key ;
    if ( 0 == Seed.length() )
        {
        Seed = "Default Seed";
        }

    // Make sure seed is at least 12 bytes long . 
    for ( Index = 0; Seed.length() < 12; Index++ )
        {
        Seed += Seed[ Index ] ;
        }

    // LFSR A, B, and C get the first, second, and
    // third four bytes of the seed, respectively.
    for ( Index = 0; Index < 4; Index++ )
        {
        m_LFSR_A = 
            ( 
            ( m_LFSR_A <<= 8 ) | 
            ( (unsigned long int) Seed[ Index + 0 ] ) 
            );
        m_LFSR_B = 
            ( 
            ( m_LFSR_B <<= 8 ) | 
            ( (unsigned long int) Seed[ Index + 4 ] ) 
            );
        m_LFSR_C = 
            ( 
            ( m_LFSR_C <<= 8 ) | 
            ( (unsigned long int) Seed[ Index + 8 ] ) 
            );
        }

    // If any LFSR contains 0x00000000, load a 
    // non-zero default value instead. 
    if ( 0x00000000 == m_LFSR_A )
        m_LFSR_A = 0x13579BDF;

    if ( 0x00000000 == m_LFSR_B )
        m_LFSR_B = 0x2468ACE0;

    if ( 0x00000000 == m_LFSR_C )
        m_LFSR_C = 0xFDB97531;

    return;
    }

void Cryptor::Transform_File
    ( 
    const std::string & Key, 
    const std::string & Target 
    )
    {
    int     Current_Char    = 'X';

    // Open the file for binary read and write.
    std::ifstream Source
        ( 
        Target.c_str(), 
        std::ios::in | std::ios::out | std::ios::binary  
        );
    std::ostream Out( Source.rdbuf() );

        // Reset the shift registers.
        Set_Key( Key );

    // Transform each character in the file.
    while ( EOF != ( Current_Char = Source.peek() ) )
        {
        Out.rdbuf()->pubseekoff
            ( 0, std::ios::cur );
        Transform_Char
            ( ( unsigned char & ) Current_Char );
        Out.put( Current_Char );
        Source.rdbuf()->pubseekoff
            ( 0, std::ios::cur );
        }   // end while ( EOF . . . 

    return;
    }

void Cryptor::Transform_String
    ( 
    const std::string & Key, 
    std::string & Target 
    )
    {
    int         Position    = 0;
    int         Length      = 0;

    // Reset the shift registers.
    Set_Key( Key );

    // Transform each character in the string.
    Length = Target.length();
    for ( Position = 0; Position < Length; Position++ )
        {
        Transform_Char
            ( ( unsigned char & ) Target[ Position ] );
        }

    return;
    }


//End of File