RosettaCodeData/Task/Password-generator/Action-/password-generator.action

126 lines
2.2 KiB
Plaintext

BYTE FUNC GetNumParam(CHAR ARRAY text BYTE min,max)
BYTE res
DO
PrintF("Input %S (%B-%B): ",text,min,max)
res=InputB()
UNTIL res>=min AND res<=max
OD
RETURN (res)
BYTE FUNC GetBoolParam(CHAR ARRAY text)
CHAR ARRAY s(255)
DO
PrintF("%S? (Y/N): ",text)
InputS(s)
IF s(0)=1 THEN
IF s(1)='y OR s(1)='Y THEN
RETURN (1)
ELSEIF s(1)='n OR s(1)='N THEN
RETURN (0)
FI
FI
OD
RETURN (0)
PROC Shuffle(CHAR ARRAY s)
BYTE i,j
CHAR tmp
i=s(0)
WHILE i>1
DO
j=Rand(i)+1
tmp=s(i) s(i)=s(j) s(j)=tmp
i==-1
OD
RETURN
BYTE FUNC Contains(CHAR ARRAY s CHAR c)
BYTE i
IF s(0)=0 THEN
RETURN (0)
FI
FOR i=1 TO s(0)
DO
IF s(i)=c THEN
RETURN (1)
FI
OD
RETURN (0)
CHAR FUNC RandChar(CHAR ARRAY s,unsafe)
BYTE len
CHAR c
len=s(0)
DO
c=s(Rand(len)+1)
UNTIL Contains(unsafe,c)=0
OD
RETURN (c)
PROC Generate(CHAR ARRAY res BYTE len,safe)
DEFINE PTR="CARD"
CHAR ARRAY st,
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ",
lower="abcdefghijklmnopqrstuvwxyz",
numbers="0123456789",
special="!""#$%&'()*+,-./:;<=>?@[]^_|",
unsafe="Il1O05S2Z"
PTR ARRAY sets(4)
BYTE i
sets(0)=upper sets(1)=lower
sets(2)=numbers sets(3)=special
res(0)=len
FOR i=1 TO len
DO
IF safe THEN
res(i)=RandChar(sets(i MOD 4),unsafe)
ELSE
res(i)=RandChar(sets(i MOD 4),"")
FI
OD
Shuffle(res)
RETURN
PROC PrintHelp()
PutE()
PrintE("Program generates random passwords")
PrintE("containing at least one upper-case")
PrintE("letter, one lower-case letter, one")
PrintE("digit and one special character.")
PrintE("It is possible to exclude visually")
PrintE("similar characters Il1O05S2Z.")
PutE()
RETURN
PROC Main()
BYTE len,count,safe,i,again,help
CHAR ARRAY password(255)
help=GetBoolParam("Show help")
IF help THEN
PrintHelp()
FI
DO
len=GetNumParam("length of password",4,30)
safe=GetBoolParam("Exclude similar chars")
count=GetNumParam("number of passwords",1,10)
PutE()
FOR i=1 TO count
DO
Generate(password,len,safe)
PrintF("%B. %S%E",i,password)
OD
PutE()
again=GetBoolParam("Generate again")
UNTIL again=0
OD
RETURN