Password Generator in tk/tcl

Share Post

The basis for this program was written in another lifetime to create basically pronouncable passwords for students.


#!/bin/sh
# pass_gen - create pronouncable passwords with 4-20 characters, 1-10 numbers
# and optional symbol
# author:Morpheus Being
# licence: GPL
# tested on
# puppy linux - initial development and testing
# xubutu
# windows xp
#
# changelog
# 1.5 - Added capital letters
# 1.4 - added template for different forms of password
# 1.3
# 1.2 - fixed random problem not choosing z u 9 etc
# 1.1 - mods to allow different lengths of vowels, letters, digits, symbols
# 1.0 - initial development
#
#\
exec wish "$0" "$@"

package require BWidget

set version "1.5"
set licence "G.P.L"
set author "Morpheus Being"
set dupdate "August 2018"

# data sets used for creating the password
set vowels { a e i o u A E I O U }
set letters { b c d f g h j k l m n p q r s t v w x y z B C D F G H J K L M N P Q R S T V W X Y Z }
set digits { 0 1 2 3 4 5 6 7 8 9 }
set symbols { ! @ # $ % ^ & * ( ) _ - + }

# -----------------------------------------------------------------------------
# appCreate - create window frame and all its contents, spinboxes, buttons,
# display elements
#
proc appCreate { } {
variable version

# menu description
set descmenu {
"&File" all file 0 {
{command "E&xit" {} "exit application" {} \
-command appExit }
}
"&Help" all help 0 {
{command "H&ow To Use" {} "how to use" {} \
-command appHelpHow }
{command "&About" {} "about the application" {} \
-command appHelpAbout }
}
}

# create the main menu
wm title . "Password Generator $version"
set wid [expr {25*[font measure mydefault 0]}]
set mainframe [MainFrame .mainframe -menu $descmenu -width $wid]

# create spinboxes for number of letters and numbers
set titf1 [TitleFrame $mainframe.titf1 -text "Number of Characters" ]
set subf1 [$titf1 getframe]
set spin1 [SpinBox $subf1.spin -range { 4 20 1 } -textvariable alpha ]

pack $spin1 -side right
pack $titf1 -fill x -pady 2 -padx 2

set titf2 [TitleFrame $mainframe.titf2 -text "Number of Numbers" ]
set subf2 [$titf2 getframe]
set spin2 [SpinBox $subf2.spin -range { 1 10 1 } -textvariable numeric ]

pack $spin2 -side right
pack $titf2 -fill x -pady 2 -padx 2

# create radio button (yes/no choice) for symbols
set titf3 [TitleFrame $mainframe.titf3 -text "Symbol"]
set subf3 [$titf3 getframe]
set rad1 [radiobutton $subf3.rad1 -text "Yes" \
-variable wantsymbol -value 1 -relief "flat"]
set rad2 [radiobutton $subf3.rad2 -text "No" \
-variable wantsymbol -value 0 -relief "flat"]

pack $rad1 $rad2 -side left
pack $titf3 -fill x -pady 2 -padx 2

# create radiobutton for format type
set titf4 [TitleFrame $mainframe.titf4 -text "Format - symbol is optional"]
set subf4 [$titf4 getframe]
set rad3 [radiobutton $subf4.rad3 -text "w(s)nw" \
-variable ftype -value 0 ]
set rad4 [radiobutton $subf4.rad4 -text "ww(s)n" \
-variable ftype -value 1 ]

pack $rad3 $rad4 -side left
pack $titf4 -fill x -pady 2 -padx 2

# create display box for generated passwords
set titf5 [TitleFrame $mainframe.titf5 -text "Password"]
set subf5 [$titf5 getframe]
set ent1 [Entry $subf5.entry -textvariable genpassword]

pack $ent1 -pady 4 -anchor w -side left
pack $titf5

# create button for generating new password
set but [Button $mainframe.but -text "New" \
-command "newPass" -helptext "create new password" ]

pack $but -side left -padx 4

wm protocol . WM_DELETE_WINDOW { appExit }
pack $mainframe -fill both -expand yes
update idletasks
}

#
# newPass - determine how many letters, vowels, digits, symbols and display the
# created password
#
proc newPass { } {
global genpassword alpha numeric wantsymbol ftype

set fpl [ expr $alpha / 2 ]

if { $alpha % 2 } {
set fpl [ expr int($alpha / 2) + 1]
}

set lpl [ expr $alpha - $fpl ]

# to change format of password edit following lines
set start [ aPart $fpl ]
set mid [ nPart $numeric ]
set end [aPart $lpl ]

# want symbol in password
if { $wantsymbol == 1 } {
set sym [ sPart ]
}

# which type of format to display
switch $ftype {
0 {
if { $wantsymbol == 1} {
set genpassword [ format "%s%s%s%s" $start $sym $mid $end ]
} else {
set genpassword [format "%s%s%s" $start $mid $end ]
}
}
1 {
if { $wantsymbol == 1} {
set genpassword [ format "%s%s%s%s" $start $end $sym $mid ]
} else {
set genpassword [format "%s%s%s" $start $end $mid ]
}
}
}
}

#
# aPart - return randomly selected letters and vowels from the lists
#
proc aPart { slen } {
global vowels letters

set vlen [ expr [ llength $vowels ] ]
set llen [ expr [ llength $letters ] ]

for { set i 0 } { $i < $slen } { incr i } { if { $i % 2 == 0 } { set randid [ expr int( rand() * $llen ) ] append ret [ lindex $letters $randid ] } else { set randid [ expr int( rand() * $vlen ) ] append ret [ lindex $vowels $randid ] } } return $ret } # # nPart - return randomly selected digit(s) from the digit list # proc nPart { slen } { global digits set dlen [ expr [ llength $digits] ] for { set i 0 } { $i < $slen } { incr i } { set randid [ expr int( rand() * $dlen ) ] append ret [ lindex $digits $randid ] } return $ret } # # sPart - return randonly selected symbol from the list # proc sPart { } { global symbols set sylen [ expr [ llength $symbols ] ] set randid [ expr int( rand() * $sylen ) ] append ret [ lindex $symbols $randid ] return $ret } # # appExit - selected from menu # proc appExit { } { set choice [ tk_messageBox -message "Are you sure you want to exit?"\ -icon question -type yesnocancel ] if {$choice == "yes" } { exit } } # appHelpHow proc appHelpHow { } { tk_messageBox -message "Select the number of\n\ - letters\n\ - numbers\n\Aug 2018 - optional symbol\n\ - format\n\ before pressing the \bNew\b button.\n" } # # appHelpAbout - display info about the program in new disposable window # proc appHelpAbout { } { global version licence author dupdate tk_messageBox -message "Written in tk/tcl.\n\ Author: $author. \n\ Date: $dupdate \n\ Updated: $update. \n\ Version: $version.\n\ Licence: $licence." } # # main procedure to manage window creation and destruction # proc main { } { wm withdraw . appCreate wm deiconify . } main #---------------------------- end of program ----------------------------------

Share Post

This site uses Akismet to reduce spam. Learn how your comment data is processed.