Extraordinary Security Measures -- NOT needed to just give 
a student his own page to get to via a password; needed for 
doing online testing and similar things where it would not 
simply be self-defeating for a student to hack/crack the system.

NOTE:  This extra security solution is just for persons who use their OWN online tests, since the 
online test building program provided at http://home.att.net/~online_tools/tools.html is sufficiently 
secure as a stand-alone.  The only thing that could possibly jeopardize any security with that system is 
if a student got a copy of the cipher program you use for encrypting and deciphering along with the 
part of the test program which parses the answers string -- requiring A LOT of JavaScript knowledge 
to know what to get and how to use it.  This possible problem can be solved by doing something that 
is described (for similar reasons) on this very web page:

[This may not make any good sense, at least until you read this page.]  The solution (as it is on 
this page) is to change the following line in the involved cipher program so the characters are in a 
different order:

this.chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\:\.\,\+\-\*\(\)\=\^\/\!\$\%\<\>\&\\;';

You could also change the character used to separate answers (and parse them) in the encrypted 
answer string -- if you can figure out how.  If you have smart hacker/cracker students who what to 
cheat this much, perhaps you should run even the tests built with my system on this web site, in the 
password-protected frames system (described here and on the pages you came from to get to this 
current web page).  (If a person this smart is a cheater, he is one sick puppy.)  BUT, DON'T LET 
ANYONE TELL YOU THERE IS NO SUCH THING AS A SECURE JAVASCRIPT TESTING 
SYSTEM .  If the level of security I describe here does not suffice, then code encryption programs 
like those you can obtain at the same site where I told you you could get a free industrial strength 
no-right-click program should be obtained (though that costs a bit of money).

Most of these directions for the 2 pages involved will read the same. 
(New or changed code will appear in BLUE.):

Make the code of the FIRST quick-referrer page (the first one  you 
PASS through after entering the password) so it is like the following 
(This is a new page you build in Notepad or SimpleText -- Save As 
 .html and with the second textbox in the Save As Dialog Box set 
 to "All Files" OR put whatever.html in quotes ("whatever.html");
there is one such page for each Password-Protected Final Destination, 
but all of these pages is almost identical ): 


(This is a page that has the same name -- before .html -- as the "password".  
In the big example on this page, it is testIt2b.html and thus "testIt2b" is the password in the 
example at the bottom.):


<html>
<head><meta name="robots" content="onindex,nofollow"><title> </title>
<script type="text/javascript">

if(top.document.URL != "http://home.att.net/~online_tools/index.html") { //  <--Change to YOUR address
top.location.replace("index.html"); // <-- change page name IF your password entry page is NOT index.html
}

// (C) 2003 CodeLifter.com
// Source: CodeLifter.com
// Do not remove this header

// Set the message for the alert box
am = "This function is disabled!";

// do not edit below this line
// ===========================
bV = parseInt(navigator.appVersion)
bNS = navigator.appName=="Netscape"
bIE = navigator.appName=="Microsoft Internet Explorer"

function nrc(e) {
if (bNS && e.which > 1){
alert(am)
return false
} else if (bIE && (event.button >1)) {
alert(am)
return false;
}
}

document.onmousedown = nrc;
if (document.layers) window.captureEvents(Event.MOUSEDOWN);
if (bNS && bV<5) window.onmousedown = nrc;


var zIdx = -1;
var akb="KW";
function Cipher() {
this.purify = purify;
this.chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\:\.\,\+\-\*\(\)\=\^\/\!\$\%\<\>\&\\;';
}
function purify(rawText) {
var cleanText = rawText;
cleanText = cleanText.replace(/\s+/g,' ');
cleanText = cleanText.replace(/[^a-zA-Z0-9\s\:\.\,\+\-\*\(\)\=\^\/\!\$\%\<\>\&\\;]/g,'');
if(cleanText.length == 0 || cleanText.match(/^\s+$/) != null) {
 return false; }
return cleanText
}
function SubstitutionCipher(name, description, algorithm) {
this.name = name;
this.description = description;
this.substitute = substitute;
this.algorithm = algorithm;
}
SubstitutionCipher.prototype = new Cipher;
function substitute(baseChar, shiftIdx, action) {
if (baseChar == ' ') { return baseChar; } 
var shiftDiff = this.chars.indexOf(baseChar) - shiftIdx;
return (this.chars.charAt((shiftDiff < 0) ? shiftDiff + this.chars.length : shiftDiff)); 
}
function vigenereAlgorithm (data, action) {
data = this.purify(data);
var keyword = this.purify(akb);
if(!keyword || keyword.match(/\^s+$/) != null) {
alert('No valid keyword for ' + (action ? 'ciphering.' : 'deciphering.'));
return false;
}
keyword = keyword.replace(/\s+/g, '');
var keywordIdx = 0;
var cipherData = '';
for (var i = 0; i < data.length; i++) {
shiftIdx = this.chars.indexOf(keyword.charAt(keywordIdx));
cipherData += this.substitute(data.charAt(i), shiftIdx, action);
keywordIdx = (keywordIdx == keyword.length - 1 ? 0 : keywordIdx + 1);
}
return cipherData;
}
var cipherArray = [
new SubstitutionCipher("vigenere","vigenere", vigenereAlgorithm),
new SubstitutionCipher("vigenere","vigenere", vigenereAlgorithm)
];
function routeCipher(data, action) {
var response = cipherArray[1].algorithm(data, action);
return response;
}





parent.frames[0].theVar = "lw";

var isNav4 = (navigator.appName =="Netscape" && parseInt(navigator.appVersion) == 4);

if (top.location.href == window.location.href) {
if (isNav4){
if(window.innerWidth != 0){
top.location.href = "index.html";  // <-- change page name IF your password entry page is NOT index.html
}
} else {
top.location.href = "index.html"; // <-- change page name IF your password entry page is NOT index.html
}
}


function doReplace() {
parent.frames[0].anotherKey = "passworded";
var addrstr = top.window.location.href;
var Itt = routeCipher(parent.frames[0].theVar,false);
var finDest = (addrstr.substr(0,34) + "secondStep" + Itt + ".html");
parent.frames[0].theVar = Itt;

location.replace(finDest);
}
</script>
</head>
<body onload="doReplace();"oncontextmenu="return false">
<p>&nbsp;</p>
</body>
</html>

Part of this requires some explanation for YOUR use: In particular, the line beginning, "var finDest=" ...

The old directions used to read: 
 
"First: ...  The 
magic "43" is gathered from A LEFT FRAME VARIABLE NAMED , "theVar" .  That goes after the first 
part of the page name.  And, then finally, the ".html" is tacked on.  That explains that line and you know 
how to change it for each password you use."  

<-- Not so now. Though this is still true with this page, but in a funny round-about way! 
      'lw' is in the place where '43' used to be.:

The lw that appears in the code above IS 43, but encrypted using the cipher at THIS LINK and using the 
keyword, KW (& which is placed as the value of the variable akb, 3 lines below the green-colored portion of 
code).  In short, using the cipher (at the link you where just told about), 43 is encrypted with the 'keyword', 
KW and that makes it lw.  "lw" is then set as a value of the theVar variable in
parent.frames[0] -- a variable 
in the left frame.  Well, that variable is sucked back out of
parent.frames[0] in the script lines, 

var Itt = routeCipher(parent.frames[0].theVar,false);
var finDest = (addrstr.substr(0,34) + "secondStep" + Itt + ".html");  

There it is sent to a DEcryptor which decrypts this back to 43 using the 'keyword' KW AND that, as usual, is 
used as part of the address to the secondStep page.   In other words, IT IS DECRYPTED AND USED.  
Also, right after that, in the source code above, the value resulting from the 
decryption (43) is set as a new value of theVar in the left frame: 
parent.frames[0].theVar = Itt;

Everything then continues as usual  -- which means you are automatically directed to the secondStep page.

In the sample users  are directed to a A SECOND Referring Page  called secondStep43.html
where users will have to provide a user-chosen second temporary password and THEN a button to actually 
get to the page they want.  The secret '43' value now assigned to theVar in the left frame will be used there.

 The rest of the description of this page continues word-for-word as before:  To wit:
"...ALSO: This first referring page 
(above) NOW includes NEW security features so you can only get to it through the password protected 
entry page (mine is index.html).  If it does not see itself in a frameset, it loads the index.html frameset ."

AND

"(Note: This (ABOVE)  is the complete code of this short page; there 
  is one such page for each password-protected Final Destination 
  pages -- but ONLY some of the text in RED changes, 1 instance to 
  another
.)" 

EXPLANATION for why we do all this for extra security:  

The explanation for this is that ONE thing a person
having reason for malice MIGHT be able to do is shut off JavaScript
between when they type in the Java password in the textbox and when
they Click the Button OR hit Enter.  This would allow them to see
the first step of the sequence and continue along with the sequence
in a very manual way without JavaScript. This amended solution takes 
care of that problem by making it VERY difficult or impractical to 
figure out the SecondStep page name (address) and thus also impossible 
to learn the Final Destination page name (address).  Once you have 
guaranteed JavaScript is running for the first referrer page SO THE 
secondStep page can be reached at all, we will now assure there is NO 
way to view, in the the source of this secondStep page, the full name 
(address) of the  Final Destination page.  A RELATED technique is 
used to have part of the Final Destination page, described 
in the next section, SECRET -- even if somehow that page's source 
gets viewed (which ONLY a person with reason for this malice would 
even try to do).

-----------------------
-----------------------

The secondStep page now can be changed to hide some of the Final 
Destination page address: 

<html>
<head>
<meta name="robots" content="onindex,nofollow">

<script language="Javascript1.2">

if(top.document.URL != "http://home.att.net/~online_tools/index.html") {  //  <--Change to YOUR address
top.location.replace("index.html"); // <-- change page name IF your password entry page is NOT index.html
}

if(parent.frames[0].anotherKey != "passworded") {
top.location.replace("index.html"); // <-- change page name IF your password entry page is NOT index.html
}

function setPW() {
var thePW = prompt("Give a PW you will have to know to use the Password-Protected Page", "!!!Set password!!!");
parent.frames[0].thePW2= thePW;
}


function doReplace() {
var addrstr = top.window.location.href;
var finDest = (addrstr.substr(0,34) + "MacScorer2" + parent.frames[0].theVar +".htm"); //  <--Change '34' &  change 
                                                                                                                                     // to YOUR page name

location.replace(finDest);
}

// The '34' above is the number of characters in the PATH MINUS THE PAGE NAME (like it was in the 
// section above). 
// YOU MUST AGAIN CHANGE THIS TO THE NUMBER OF CHARACTERS IN *YOUR* PATH - .


// (C) 2003 CodeLifter.com
// Source: CodeLifter.com
// Do not remove this header

// Set the message for the alert box
am = "This function is disabled!";

// do not edit below this line
// ===========================
bV = parseInt(navigator.appVersion)
bNS = navigator.appName=="Netscape"
bIE = navigator.appName=="Microsoft Internet Explorer"

function nrc(e) {
if (bNS && e.which > 1){
alert(am)
return false
} else if (bIE && (event.button >1)) {
alert(am)
return false;
}
}

document.onmousedown = nrc;
if (document.layers) window.captureEvents(Event.MOUSEDOWN);
if (bNS && bV<5) window.onmousedown = nrc;


</script>

<title> </title>

</head>
<body oncontextmenu="return false">
<p>&nbsp;</p>

<center><p>FIRST:</p>
<input type="button" value="Click to set temporary (session) password" onclick="setPW();" />
<p>THEN:</p>
<input type="button" value="CLICK HERE" onclick="doReplace();" />
</center>
<p>&nbsp;</p>
</body>
</html>

The name of the Final Destination page must be something ending in '43' because this 
value is tacked onto the name of the page you are transferred to.  SO, now using 
the current example, the Final Destination page would be MacScorer43.htm .

If you want it to be something other than 43, then encrypt another number other than '43' 
and supply it to the line parent.frames[0].theVar = "lw"; in the LAST page's code.  Also, 
of course, supply the 'keyword' that you used for the encryption in the line, 

var akb="KW";
-- which also appears in the code of the last page.  I used '43' and
encrypted it to 'lw' using the 'keyword', 'KW'  .  Again, the encryption
program used is via THIS LINK.

-----------------------
-----------------------

This password-protected entry frameset would now be usable for
giving tests -- a case where a user would want to defeat the system.
For normal use, of a individual's student own accessible web page, 
one would not need to worry about such malice and thus would
not need to use these techniques.  [Users of this system should know
that what stands in the spot of the '43' need not just be numbers --
numbers and/or letters can be used and upper case is different than
lower case (thus there are WAY more than 99 ways the page names
can end!!; and this is not to mention that many other characters -- 
about any used in math -- can also be used in the 'keyword').] 

Now for the really super-paranoid.  IF you believe one of your 
students know the cipher you use, just go to THE CIPHER LINK
View the Source of the cipher, Save your own copy (as mycipher.htm) 
 and change the ORDER of the characters in 

'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\:\.\,\+\-\*\(\)\=\^\/\!\$\%\<\>\&\\;';

in  both YOUR own cipher, that you use to encrypt page endings
with a 'keyword', *AND* in the line of code in the FIRST page above!
If your students can then guess things, they are psychic.

Ok, ok ... I know the super, super really paranoid want more.  So, 
here's a final bit: 
I know some of you must be nervous that the last characters 
of both the secondStep and the Final Destination page are the same.  
Here is a solution to solve that:  Change the final line of the 3-line 
code block in the First Referrer page, so it reads as follows:

var Itt = routeCipher(parent.frames[0].theVar,false);
var finDest = (addrstr.substr(0,34) + "secondStep" + Itt + ".html");
parent.frames[0].theVar = routeCipher(Itt,false);

Now, the last two characters of the Final Destination page sought 
when the second button is clicked on the secondStep page will be 
'lw' double-DEcrypted -- which is as good as encrypting.  'lw' 
double-decrypted is 'uh' and thus (of course) that is what you have 
to have the final two characters of the Final Destination page (before 
the .htm ) be.  Thus, for the example I have been using, the Final 
Destination page would be MacScorer2uh.htm .  

[One final thing, for some reason a "-" cannot be part of the 'keyword' 
used in the cipher (this bug is for unknown reasons), so that math 
symbol cannot be used in the 'keyword'.  Of course, you will test your 
program to see if any similar bugs appear in it.]

If you need more security, you will have to get server rights or your
own commercial grade web site.