@if (@coltransencrypt != @coltransencrypt)

@set @coltransencrypt = 1

function permutationGenerator(nNumElements)
{
	this.nNumElements     = nNumElements;
	this.antranspositions = new Array;
	var k = 0;

	for (i = 0; i < nNumElements - 1; i++)
		for (j = i + 1; j < nNumElements; j++)
			this.antranspositions[ k++ ] = ( i << 8 ) | j;

	// keep two positions as lo and hi byte!
	this.nNumtranspositions = k;

}
permutationGenerator.prototype.fromCycle = function(anCycle)
{
	var anpermutation = new Array(this.nNumElements);

	for (var i = 0; i < this.nNumElements; i++) anpermutation[i] = i;
	
	for (var i = 0; i < anCycle.length; i++)
	{
		var nT = this.antranspositions[anCycle[i]];
		var n1 = nT & 255;
		var n2 = (nT >> 8) & 255;
		nT = anpermutation[n1];
		anpermutation[n1] = anpermutation[n2];
		anpermutation[n2] = nT;
	}

	return anpermutation;
}

function password(strpasswd)
{
	this.strpasswd = strpasswd;
}
password.prototype.getHashValue = function()
{
	var m = 2096597;
	var a = 971;

	var h = 0;

	for (var i = 0; i < this.strpasswd.length; i++) 
		h = (h * a + this.strpasswd.charCodeAt(i)) % m;

	return h;
}
password.prototype.getpermutation = function()
{
	var nNUMELEMENTS = 13;
	var nCYCLELENGTH = 21;
	
	pg = new permutationGenerator(nNUMELEMENTS);
	
	var anCycle = new Array(nCYCLELENGTH);
	var npred   = this.getHashValue();

	for (var i = 0; i < nCYCLELENGTH; i++)
	{
		npred = 839 * npred % 2096597;
		anCycle[i] = npred % pg.nNumtranspositions;
	}

	return pg.fromCycle(anCycle);
}

function SecureContext(strText)
{
	this.strText			= strText;
	this.transliterate = SecureContext_transliterate;
	this.encypher      = SecureContext_encypher;
	this.decypher      = SecureContext_decypher;
	this.sign          = SecureContext_pad;
	this.secure   = SecureContext_secure;
	this.unsecure = SecureContext_unsecure;
}

function SecureContext_transliterate(btransliterate)
{
	this.strText = transliterate(this.strText, btransliterate)
}

function transliterate(str, btransliterate)
{
	var strDest = '';

	var nTextIter  = 0;
	var nTexttrail = 0;

	while (nTextIter < str.length)
	{
		var strRun = '';
		var cSkipped   = 0;

		while (cSkipped < 7 && nTextIter < str.length)
		{
			var chT = str.charAt(nTextIter++);
			if (-1 == strRun.indexOf(chT))
			{
				strRun += chT;
				cSkipped = 0;
			}
			else cSkipped++;
		}

		while (nTexttrail < nTextIter)
		{
			var nRunIdx = strRun.indexOf(str.charAt(nTexttrail++));
			if (btransliterate)
			{
				nRunIdx++
				if (nRunIdx == strRun.length) nRunIdx = 0;
			}
			else
			{
				nRunIdx--;
				if (nRunIdx == -1) nRunIdx += strRun.length;
			}
			strDest += strRun.charAt(nRunIdx);
		}

	}

	return strDest;
}



function SecureContext_encypher(anperm)
{	
	var strEncyph = '';
	var nCols     = anperm.length;
	var nRows     = this.strText.length / nCols;
	
	for (var i = 0; i < nCols; i++)
	{
		var k = anperm[ i ];
		for (var j = 0; j < nRows; j++)
		{
			strEncyph += this.strText.charAt(k);
			k         += nCols;
		}
	}
	
	this.strText = strEncyph;
}

function SecureContext_decypher(anperm)
{
	var nRows    = anperm.length;
	var nCols    = this.strText.length / nRows;
	var anRowOfs = new Array;
	
	for (var i = 0 ; i < nRows; i++) anRowOfs[ anperm[ i ] ] = i * nCols;

	var strplain = '';
	for (var i = 0; i < nCols; i++)
	{
		for (var j = 0; j < nRows; j++)
			strplain += this.strText.charAt(anRowOfs[ j ] + i);
	}

	this.strText = strplain;
}

function SecureContext_pad(nCols, rsPad)
{

	if (typeof(rsPad) == "undefined") rsPad = ' ';
	var nTextLen     = this.strText.length;
	var nMissingCols = nCols - (nTextLen % nCols);
	var strpadding   = '';  

	if (nMissingCols < nCols)
		for (var i = 0; i < nMissingCols; i++) strpadding += rsPad;

	this.strText +=  strpadding;
}

function SecureContext_secure(strpasswd, rsPad)
{
	var passwd = new password(strpasswd);
	var anperm   = passwd.getpermutation()
	this.sign(anperm.length, rsPad);
	this.transliterate(true);
	this.encypher(anperm);
}

function SecureContext_unsecure(strpasswd)
{
	var passwd = new password(strpasswd);
	var anperm = passwd.getpermutation();
	this.decypher(anperm);
	this.transliterate(false);
	return true;
}

function GetCryptText(rsPlain, rsPassword, rsPad)
{
	var sc = new SecureContext(rsPlain);

	sc.secure(rsPassword, rsPad);

	return sc.strText;
	
}

function GetPlainText(rsCrypt, rsPassword)
{
	
	var sc = new SecureContext(rsCrypt);
	
	sc.unsecure(rsPassword);
	
	return sc.strText;

}

@end

