Version 3 of vignere

Updated 2002-01-22 16:45:33

The Vigen�re cipher is a symmetric polyalphabetic cipher devised in the 16th century by Blaise de Vigen�re It was considered unbreakable up until 1863 but now is considered to be weak as it is subject to key analysis and frequency analysis.

Vigen�re's method is a variation of the Caesar rotational cipher. A table of rotated alphabets is formed where each row is rotated by n + 1. The value of the key text gives the row to use for encrypting the corresponding character in the plain text.

References

M. Gardner, Codes, Ciphers, and Secret Writing, Dover Publications, Inc., 1972

http://www.trincoll.edu/depts/cpsc/cryptography/vigenere.html

http://math.ucsd.edu/~crypto/java/EARLYCIPHERS/Vigenere.html

Usage

 % vigen�re::vigen�re -key Tcl "The Tcl'ers Wiki"
 Mjp Mew'xtd Pkvb
 % vigen�re::vigen�re -key Tcl -mode decode {Mjp Mew'xtd Pkvb}
 The Tcl'ers Wiki

 # vigenere.tcl - Copyright (C) 2002 Pat Thoyts <[email protected]>
 #
 # Provide a Tcl only implementation of the Vigen�re cipher.
 #
 # -------------------------------------------------------------------------
 # See the file "license.terms" for information on usage and redistribution
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 # -------------------------------------------------------------------------
 # @(#)$Id: 2884,v 1.4 2002-06-21 04:29:58 jcw Exp $

 namespace eval vigen�re {
     namespace export vigen�re

     interp alias {} [namespace current]::encode \
         {} [namespace current]::Cipher encode
     interp alias {} [namespace current]::decode \
         {} [namespace current]::Cipher decode
 }

 # -------------------------------------------------------------------------
 # Description:
 #  An implementation of the Vigen�re symmetric polyalphabetic cipher.
 #  In this cipher each letter is encoded using a caesar rotation given by the
 #  value of the corresponding letter in the key.
 #
 proc vigen�re::Cipher {mode key plaintext} {
     binary scan $plaintext c* plainchars
     set K [Shifts $mode $key]
     set N 0
     set M [llength $K]
     foreach c $plainchars {
         set n [lindex $K $N]
         set C [expr {
                      (($c ^ 0x40) & 0x5F) < 27 ? 
                      (((($c ^ 0x40) & 0x5F) + $n - 1) % 26 + 1) | ($c & 0xe0)
                      : $c
                  }]
         if {$c != $C} {
             incr N
             if {$N >= $M} { set N 0}
         }
         append r [format %c $C]
     }
     return $r
 }

 # -------------------------------------------------------------------------
 # Description:
 #  The cipher operates by converting the key phrase into a sequence of shift 
 #  values from 1 to 26 that correspond to Caesar alphabets to use for enciphering
 #  the current character. This procedure calculates the shifts from the key text.
 #
 proc vigen�re::Shifts {mode keytext} {
     binary scan $keytext c* keychars
     set encode [string match "encode" $mode]
     foreach kc $keychars {
         set v [expr {($kc & 0x5f) - 0x41}]
         if {$encode} {
             lappend shifts $v
         } else {
             lappend shifts [expr {abs($v - 26)}]
         }
     }
     return $shifts
 }

 # -------------------------------------------------------------------------
 # Description:
 #  Encrypt data using the Vigen�re cipher. Not secure (but better that rot13!)
 #
 proc vigen�re::vigen�re {args} {
     array set opts {filename {} mode encode key {}}
     while {[string match -* [lindex $args 0]]} {
         switch -glob -- [lindex $args 0] {
             -k* {
                 set opts(key) [lindex $args 1]
                 set args [lreplace $args 0 0]
             }                
             -m* {
                 set opts(mode) [lindex $args 1]
                 set args [lreplace $args 0 0]
             }                
             -f* {
                 set opts(filename) [lindex $args 1]
                 set args [lreplace $args 0 0]
             }
             -- {
                 set args [lreplace $args 0 0]
                 break
             }
             default {
                 return -code error "bad option [lindex $args 0]:\
                       must be -key, -mode, -filename or --"
             }
         }
         set args [lreplace $args 0 0]
     }

     if {$opts(key) == {}} {
         return -code error "invalid args: -key must be specified"
     }

     if {$opts(filename) != {}} {
         set f [open $opts(filename) r]
         #fconfigure $f -translation binary
         set data [read $f]
         close $f
     } else {
         if {[llength $args] != 1} {
             return -code error "wrong \# args: should be\
                   \"vigen�re ?-mode mode? -key phrase -file name | data\""
         }
         set data [lindex $args 0]
     }

     if {[string match "encode" $opts(mode)]} {
         return [encode $opts(key) $data]
     } else {
         return [decode $opts(key) $data]
     }
 }

 # -------------------------------------------------------------------------

 package provide vigen�re 1.0

 # -------------------------------------------------------------------------
 #
 # Local variables:
 #   mode: tcl
 #   indent-tabs-mode: nil
 # End:

See also uuencode, base64, caesar, rot13

Category Package Category Cryptography