TMSWeb Technical Documentation

(This document lives at
If you have received a printed version, consult the URL for the most current version

Introduction to TMSWeb

TMSWeb is...

TMSWeb HTML Test Fields Format

TMSWeb tests are delivered from the web-server to the client browser as HTML pages which contain a set of forms with hidden fields which are structured so as to contain within them the entire test content.  The specific set of questions delivered to a a single testing instance may reflect a randomization and selection of questions performed on the server side; but in all cases, the complete set of question material to be completed by an end user is contained within the single initially delivered HTML test page sent to the client.

Once a complete test is delivered to a client (as a set of hidden fields), a Javascript program at the client side performs all the work of answering the actual questions.  Once answers are given to questions, these answers are also stored during the testing session within the same hidden fields as the test content.  The advantage of our approach is to reduce sensitivity to network problems, and allow completion of testing even in the event of a connection disruption during the test session.  Downloading a single initial HTML page should take only a matter of seconds, while a testing session may potentially last hours (depending on the test content).  It would be an unnecessary inconvenience to users to have a testing session, already in progress, disrupted by a network or server problem--especially if the test is of long duration or carries accreditation hours.  However, our approach does admittedly carry with it a corresponding drawback in that a client-side software problem can potentially destroy the partial results of a testing session, since the interim results are stored only within the client-browser memory space until results are specifically submitted.

A delivered test has the following structure:

(GENERATOR may differ according to test source)
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> 
<TITLE>Name of Test</TITLE> 
<SCRIPT LANGUAGE="JavaScript" SRC="../scripts/testfuncs.js"> 
     document.write("Included JS file not found")</SCRIPT> 
Body Tag: 
(Client individualization may use different body tag)
<BODY TEXT="#000000" BGCOLOR="#E0FFAD" LINK="#0000CC"  
     VLINK="#FF00FF" ALINK="#FFFF00">
Form per Question: 
(This block is repeated for each question within the delivered test, with appropriate contents for each question.  Every question in TMSWeb has a unique ID.  Correct answer is sent in encrypted form to allow offline scoring if the need arises.  Response field is filled in as user answers the questions.)
<INPUT TYPE="hidden" NAME="id" VALUE="100010101"> 
<INPUT TYPE="hidden" NAME="qtype" VALUE="multiple"> 
<INPUT TYPE="hidden" NAME="question" VALUE="The Series 63 Agent State Law Examination tests knowledge of:"> 
<INPUT TYPE="hidden" NAME="answer1" VALUE="Blue Sky laws; "> 
<INPUT TYPE="hidden" NAME="answer2" VALUE="securities laws in the particular state in which the agent seeks a license;"> 
<INPUT TYPE="hidden" NAME="answer3" VALUE="the Uniform Securities Act; "> 
<INPUT TYPE="hidden" NAME="answer4" VALUE="none of the above. "> 
<INPUT TYPE="hidden" NAME="correct" VALUE="X"> 
<INPUT TYPE="hidden" NAME="response" VALUE=""> 
Page Closing: 
(Javascript function is called within initial page to begin question administration)
<SCRIPT LANGUAGE="JavaScript"> AllQuestions(0); </SCRIPT> 
An advantage of our approach to test delivery is that the appearance of test can be customized for specific clients, or for other differentiations in tests, without any modification of test content itself.  Any visual or interface modification to test administration would be made wholly within testfuncs.js testing engine.  This would allow, for example, an identical test to by administered in a very different visual form to different Ariadne licensees.

TMSWeb Javascript Testing Engine

The specific code and methods employed by the testing engine are proprietary to Gnosis Software, Inc..  However, a general description of what the testing engine does is presented below.

Once an HTML test is delivered, with its hidden fields reflecting question content, the testfuncs.js testing engine performs the following tasks:

  1. Question content is "unhidden" in order to allow a presentation of a question to a user.
  2. When a response to a question is given, it is stored back to the "response" field of that question.
  3. A means of navigating through the questions is provided in the form of buttons, lists, or whatever interface is required by a specific licensee.
  4. Upon completion (or partial completion) of a test, the set of responses indicated is sent back to a server CGI application where it is stored and evaluated.

TMSWeb Answer Encryption

The following algorithm is used to encrypt the "correct" field included within an HTML formatted test.  As a general characterization, this algorithm is designed to be sufficiently difficult to assure that an attempt at cryptanalysis would require significantly more work than would merely preparing on the test material.  However, no pretense is made that the TMSCrypt() algorithm would be secure if extended to full-blown communications security.  That is not its intention, nor does it succeed in such.  The TMSCrypt() algorithm, although documented publicly herein remains the property of Gnosis Software, Inc.

The below algorithm is reproduced in an xBase implementation, since we find that to be a highly readable syntax.  The actual implementation used in a specific system may be in a different programming language, although it will produce identical results.  Decryption is a straightforward reversal of the encryption algorithm.  The key(s) used in encryption and decryption will, of course, be kept secretly by Gnosis Software, Inc. only.

FUNCTION TMSCrypt(answer, idno, cPassword)
*  'answer' is the actual single letter correct answer to a question
*  'idno' is the unique 9 character numeric identifier of a question
*  'cPassword' is a nine character string
LOCAL i, Rotation, Secret[9]

// No encryption is performed on answers outside the expected answer space
IF AT(answer,'ABCD') = 0

// Secret key consists of a sequence of nine integers
// (i.e. numeric values of letters of nine-digit password; A=1,B=2,...)
Secret := ParsePW(cPassword)

// Initialize Rotation
Rotation := 1

// Iteratively diffuse map for each digit of idno/Secret
FOR i = 1 to LEN(idno)
 Rotation = Rotation * (Secret[i] + VAL(SUBSTR(idno,i,1)) )
 Rotation = (Rotation % 23) + 1
Rotation = (Rotation % 4) + 1

// Transform answer according to computed rotation
 CASE Rotation = 1
   CASE answer = "A"  ;  RETURN("W")
   CASE answer = "B"  ;  RETURN("X")
   CASE answer = "C"  ;  RETURN("Y")
   CASE answer = "D"  ;  RETURN("Z")
 CASE Rotation = 2
   CASE answer = "B"  ;  RETURN("W")
   CASE answer = "C"  ;  RETURN("X")
   CASE answer = "D"  ;  RETURN("Y")
   CASE answer = "A"  ;  RETURN("Z")
 CASE Rotation = 3
   CASE answer = "C"  ;  RETURN("W")
   CASE answer = "D"  ;  RETURN("X")
   CASE answer = "A"  ;  RETURN("Y")
   CASE answer = "B"  ;  RETURN("Z")
 CASE Rotation = 4
   CASE answer = "D"  ;  RETURN("W")
   CASE answer = "A"  ;  RETURN("X")
   CASE answer = "B"  ;  RETURN("Y")
   CASE answer = "C"  ;  RETURN("Z")