#!/usr/local/bin/tclsh #the book uses a=0,b=1,... try to accomodate. #string of letters set alphabet "abcdefghijklmnopqrstuvwxyz" #list of letters for {set ii 0} {$ii < 26} {incr ii} { lappend alphalist [string index $alphabet $ii] } #list of digraphs for {set ii 0} {$ii < 26} {incr ii} { for {set jj 0} {$jj < 26} {incr jj} { lappend digraphs "[string index $alphabet $ii][string index $alphabet $jj]" }} #transforms letter sequence into number sequence proc LTN {sentence} { global alphabet set no [string length $sentence] set number "" for {set ii 0} {$ii < $no} {incr ii} { for {set jj 0} {$jj < 26} {incr jj} { if {[string index $sentence $ii] == [string index $alphabet $jj]} { if {$jj <= 9} { append number "0$jj" } else { append number "$jj" } } }} return $number } #transforms number sequence into letter sequence proc NTL {number} { global alphabet set no [string length $number] set sentence "" for {set ii 0} {$ii < $no} {incr ii 2} { set bo [string range $number $ii [expr {$ii + 1}]] if {$bo == "08"} { append sentence "i" } elseif {$bo == "09"} { append sentence "j" } elseif {$bo < 26} { append sentence [string index $alphabet $bo] } } return $sentence } #Vigenere cypher cc=1 to encrypt and cc=-1 to decrypt proc Vig {text key cc} { global alphabet set le [string length $key] set kn [LTN $key] set tn [LTN $text] set no [string length $text] set out "" for {set ii 0} {$ii < $no} {incr ii} { set bo [string range $tn [expr {2*$ii}] [expr {2*$ii + 1}]] if {$bo == "08"} { set bo 8 } elseif {$bo == "09"} { set bo 9 } set off [string range $kn [expr {2*($ii%$le)}] [expr {2*($ii%$le) +1}]] if {$off == "08"} { set off 8 } elseif {$off == "09"} { set off 9 } set ga [expr {($bo + $cc*$off)%26}] append out [string index $alphabet $ga] } return $out } #outputs the pari result of foo, only in the dept. linux system proc pari_gp {foo} { set a [exec echo $foo | gp-2.1] return [string range $a 605 [expr [string length $a ] -11]] } #shuffling a list. From the wiki proc shuffle { list } { set n 1 set slist {} foreach item $list { set index [expr {int(rand()*$n)}] set slist [linsert [lindex [list $slist [set slist {}]] 0] $index $item] incr n } return $slist } #makes a random substitution encypherment of foo proc Sub {foo} { global alphabet alphalist set key [shuffle $alphalist] set no [string length $foo] set out "" for {set ii 0} {$ii < $no} {incr ii} { for {set jj 0} {$jj < 26} {incr jj} { if {[string index $foo $ii] == [string index $alphabet $jj]} { append out [lindex $key $jj] } }} return $out } #counts the number of occurrences of foo in bar proc Count {foo bar} { set r 0 set temp $bar set po [string first $foo $bar] while {$po != -1} { incr r set temp [string range $temp [expr {$po + 1}] end] set po [string first $foo $temp] } return $r } #counts the appearances of each letter and digraph in bar proc Profile {bar} { global alphalist digraphs foreach letter $alphalist { puts "$letter [Count $letter $bar]" } foreach dig $digraphs { set cc [Count $dig $bar] if {$cc > 0} { puts "$dig $cc" } } } proc ShortProfile {bar} { global alphalist set li foreach letter $alphalist { list append $li {[Count $letter $bar] $letter} } set li [lsort $li] return $li }