Version 3 of Vigenere

Updated 2009-04-02 13:23:08 by LGT

Here is a program that applies Vigenère's encryption method [L1 ] to files.

At first It transposes inputs to base 64 encoding [L2 ], then it applies Vigenere's method.

        # vigenere.tcl --
        #
        #         provide method to encrypt and decrypt a file following vigenere algorithm.
        #
        #       encrypt read from a input stream and write encrypted data to an output stream.
        #       decrypt read from a encrypted input stream and write decrypted (clear) data to an output stream.
        #       streams should be "fconfigure"'d with "-translation binary" option.
        #
        # Copyright (c) 2009 Laurent Gateau.
        #
        # version 1.0
        #
        package require base64

        namespace eval vigenere {
                namespace export Encrypt Decrypt EncryptFile DecryptFile        
                variable alphabet64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
                variable bufferlen 72
                variable version "1.0"
        }

        # vigenere::engine --
        #
        # Arguments: 
        #    key and data variables must be part of alphabet64 (i.e. : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" and optionnaly "=")
        #    key and data variables might result from ::base64::encode calls
        #    encode must be either 1 (encode) or 0 (decode)
        #
        # Results:
        #    result is a cyphered string containing symbols from alphabet64
        #
        proc vigenere::engine { key data {encode -encode}} {
                        variable alphabet64
                        set result ""
                        set ii 0
                        set keylen [string length $key]
                        while {$ii < [string length $data]} {
                                set car [string index $data $ii]                        
                                if {$encode && ($car == "=")} {
                                        incr ii
                                        continue
                                }
                                set keyii [expr $ii % $keylen]
                                set keycar [string index $key $keyii]
                                set index1 [string first $car $alphabet64]
                                set index2 [string first $keycar $alphabet64]                        
                                if {$encode} {
                                        set jj [expr ($index1 + $index2) % 64]
                                } else {
                                        set jj [expr ($index1 - $index2) % 64]                
                                }
                                append result "[string index $alphabet64 $jj]"
                                incr ii
                        }
                        return $result
        }

        # vigenere::encode --        
        #
        # Arguments: 
        #    key and data variables must be part of alphabet64 (i.e. : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" and optionnaly "=")
        #    key and data variables might result from ::base64::encode calls
        #
        # Results:
        #    result is a cyphered string containing symbols from alphabet64
        #
        proc vigenere::encode { key data } {
                return [vigenere::engine "$key" "$data" 1]
        }

        # vigenere::decode --
        #
        # Arguments: 
        #    key and data variables must contains only symbol from alphabet64 (i.e. : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" and optionnaly "=")
        #    key variable might result from a call of ::base64::encode
        #
        # Results:
        #    result is a clear string containing symbols from alphabet64
        #    result might be a parameter given to a call of ::base64::decode
        #
        proc vigenere::decode { key data } {
                return [vigenere::engine "$key" "$data" 0]
        }

        # vigenere::encrypt --
        #
        # Arguments:
        #    key is a pass phrase ; the longer the better secrets are kept.
        #    fin is the input stream
        #    fout is the output stream 
        # Results:
        #    fin has reached its end
        #    fout has been written with encrypted data
        #
        proc vigenere::encrypt { key fin fout } {
                variable bufferlen
                while { ! [eof $fin] } {
                        set input [read $fin $bufferlen]
                        set data [::base64::encode -maxlen [expr $bufferlen * 4 / 3] $input]
                        puts $fout [::vigenere::encode [::base64::encode "$key"] "$data"]
                }
        }

        # vigenere::decrypt --
        #
        # Arguments: 
        #   key is a pass phrase ; the longer the better secrets are kept.
        #   fin is the input stream
        #   fout is the output stream
        # 
        # Results:
        #   fin has reached its end
        #   fout has been written with decrypted (clear) data.
        #
        proc vigenere::decrypt { key fin fout } {
                while { ! [eof $fin] } {
                        set input [gets $fin]
                        set data [::vigenere::decode [::base64::encode "$key"] "$input"]
                        puts -nonewline $fout [::base64::decode "$data"]
                }
        }        

        # vigenere::command --
        #
        # Arguments:
        #    command line arguments : arc and argv
        #    mode is either -encrypt or -decrypt
        #    key is the cypher key
        #    input file name
        #    output file name
        #
        # Results:
        #    write output file or display usage.
        #
        proc vigenere::command {} {
                global argc argv
                if { $argc > 0 } {
                        set mode [lindex $argv 0]                
                        set key [lindex $argv 1]
                        switch -exact -- $mode {
                                -encrypt {
                                        set fin [open [lindex $argv 2] "r"]
                                        fconfigure $fin -translation binary
                                        set fout [open [lindex $argv 3] "w"]
                                        fconfigure $fout -translation binary
                                        encrypt "$key" $fin $fout        
                                }
                                -decrypt {
                                        set fin [open [lindex $argv 2] "r"]
                                        fconfigure $fin -translation binary
                                        set fout [open [lindex $argv 3] "w"]
                                        fconfigure $fout -translation binary
                                        decrypt "$key" $fin $fout                                
                                }
                                default {
                                        puts "usage: (-encrypt|-decrypt) key input_file output_file"
                                }
                        }
                }
        }

        package provide vigenere $::vigenere::version

        vigenere::command 

enter categories here