Here is a program that applies Vigenère's encryption method [http://en.wikipedia.org/wiki/Vigenère_cipher] to files.
At first It transposes input to base 64 encoding [http://wiki.tcl.tk/588], then it applies Vigenere's algorithm.
The file .vgnr in home directory contains the key or secret used to encrypt, decrypt.
Usage is, to encrypt :
tclsh vigenere.tcl -filencrypt "amye
=> thise will create ka directory" ivgnpur and create a file.b winth the same file.name but with encrypted content
to decrypt :
tclsh vigenere.tcl -dvgnr/filename
=> this will crypeate "ma directory sclear and creat key" file.name but with decrypted countputfile.bint
md5sum filename and md5sum clear/filename give the same md5sum.
The source code is also stored at [http://defwxyz.free.fr/vigenere.txt] and at [http://defwxyz.free.fr/vigenere.html]
Here is the source code :
======
#! /usr/local/bin/tclsh8.6
# vigenere.tcl --
#
# encrypt, decrypt a file following vigenere algorithm.
#
# a secret or key must be present as a file named .vgnr in home directory
#
# example:
#
# tclsh vigenere.tcl notes.txt
# => will produce the file vgnr/notes.txt (encryption)
# tclsh vigenere.tcl vgnr/notes.txt
# => will produce the file clear/notes.txt (decryption)
#
# Copyright (c) 2009-2022 Laurent Gateau.
#
# version 1.3
#
package require Tcl 8.6
namespace eval vigenere {
namespace export encode decode encrypt decrypt
variable alphabet64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
variable bufferlen 57
variable version "1.3"
}
# vigenere::engine --
#
# Arguments:
# key and data variables must be part of alphabet64
# key and data variables might result from binary encode base64 call
# 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
# key and data variables might result from binary encode base64 call
#
# 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
# key variable might result from a call of binary decode base64
#
# Results:
# result is a clear string containing symbols from alphabet64
# result might be a parameter given to a call of binary decode base64
#
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 [binary encode base64 -maxlen [expr $bufferlen * 4 / 3] $input]
puts $fout [::vigenere::encode [binary encode base64 "$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 [binary encode base64 "$key"] "$input"]
puts -nonewline $fout [binary decode base64 "$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 == 1 } {
set keyfile [open "~/.vgnr" "r"]
fconfigure $keyfile -translation binary
set key [read $keyfile]
close $keyfile
set filename [lindex $argv 0]
set outFilename ${filename}.out
if [string match "vgnr/*" $filename] {
set mode "-decrypt"
set outFilename "clear/[string range $filename 5 end]"
if {![file exists "clear"]} {
file mkdir "clear"
}
} else {
set mode "-encrypt"
set outFilename "vgnr/${filename}"
if {![file exists "vgnr"]} {
file mkdir "vgnr"
}
}
switch -exact -- $mode {
-encrypt {
set fin [open $filename "r"]
fconfigure $fin -translation binary
set fout [open $outFilename "w"]
fconfigure $fout -translation binary
encrypt "$key" $fin $fout
exit 0
}
-decrypt {
set fin [open $filename "r"]
fconfigure $fin -translation binary
set fout [open $outFilename "w"]
fconfigure $fout -translation binary
decrypt "$key" $fin $fout
exit 0
}
}
}
::vigenere::usage
}
proc vigenere::usage {} {
puts "usage: vigenere [vgnr/]<file>"
puts " file ~/.vgnr must exists and will be the secret key"
puts " example: vigenere input_file"
puts " encrypt input_file as vgnr/input_file"
puts " example: vigenere vgnr/input_file"
puts " decrypt vgnr/input_file as clear/input_file"
exit 1
}
package provide vigenere $::vigenere::version
vigenere::command
======
See also [Base 64 encode/decode] [http://wiki.tcl.tk/2884]
<<categories>> Package | Cryptography