Edit in JSFiddle

var shiftBy = 2;
var alphabet = ['o', '!', 'W'];
var alphabetLength = alphabet.length;

// Write the character set: the linguistic alphabet used for this example...
document.getElementById("charSet").innerHTML = '<i>The Alphabet for this Exercise is<br />Limited to a Set of ' + alphabetLength + ' Characters for Simplicity:</i> <br /><span style="color: magenta;">' + alphabet + '</span>';

// 'message' is the message to undergo encryption...
var message = "WoW!";
var messageLength = message.length;

var i = 0;
var temp;
var myAscii = [];

for (i = 0; i < messageLength; i++)
{
	temp = message.charAt(i);
	myAscii[i] = alphabet.indexOf(temp) + shiftBy;
}

// Write the initial message and its myAscii equivalent...
document.getElementById("inputText").innerHTML = '<i>Original Message:</i> <br /><span style="color: blue;">' + message + '</span>';
document.getElementById("outputMyAscii").innerHTML = '<i>Converted to myAscii Values:</i> <br /><span style="color: orange;">' + myAscii + '</span>';

// p and q are two primes such that...
// p times q must be greater than 5 since I'm splitting
// the coded character string into individual characters
// whose greatest myAscii value will be less than 6
var p =7;
var q = 5;

var n = p * q; // 35
var phi = (p - 1) * (q - 1); // 24

// thanks to Wolfram Alpha...
// https://www.wolframalpha.com/input/?i=factor+24
// the prime factorization of phi, namely 24, is:
// 2^3 x 3  (4 prime factors, 2 distinct)

// 'e' must not be a factor of 'phi'
// gcd(e, phi) = 1
// Hence...
// gcd(29, 24) = 1
// https://www.wolframalpha.com/input/?i=gcd(29,+24)
// and must be less than 'n'
// Hence...
// e < n --> 29 < 35
var e = 29;

// solve e(d) = 1 (mod phi)
// solve 29(d) = 1 (mod 24)
// https://www.wolframalpha.com/input/?i=solve+29(d)+%3D+1+(mod+24)
var d = 5;

var encodingProcedure = 'Select two primes, <b>p</b> and <b>q</b>: <b>' + p + '</b> and <b>' + q + '</b>.';
encodingProcedure += '<br /><b>n</b> = p &times; q &nbsp;&lt;&mdash;&gt;&nbsp; <b>' + n + '</b> = ' + p;
encodingProcedure += ' &times; ' + q + '<br /><b>&phi;</b> = (p &minus; 1) &times; (q &minus; 1) ';
encodingProcedure += '&nbsp;&lt;&mdash;&gt;&nbsp; <b>' + phi + '</b> = (' + p + ' - 1) &times; (' + q + ' - 1)';
encodingProcedure += '<br /><b>E</b> must not be a factor of <b>&phi;</b>[Greek letter: <b>phi</b>],';
encodingProcedure += ' and <b>e</b> must be less than <b>n</b>.<br />Hence, the <i>Greatest';
encodingProcedure += ' Common Divisor</i> of <b>e</b> and <b>&phi;</b> must equal <b>1</b>.<br />';
encodingProcedure += 'I choose <b>e</b> = <b>' + e + '</b>. Thus, the <b>GCD(' + e + ', ' + phi;
encodingProcedure += ') = 1</b>, and <b>' + e + '</b> &lt; <b>' + n + '</b>.<br />Solve for <b>d</b> ';
encodingProcedure += '&nbsp;&lt;&mdash;&gt;&nbsp; e(<b>d</b>) = 1 (mod &phi;) &nbsp;&lt;&mdash;&gt;&nbsp; ' + e;
encodingProcedure += '(<b>' + d + '</b>) = 1 (mod ' + phi + ').<br />So, <b>d</b> is equal to <b>' + d + '</b>.';
var charValues = [];
for (i = 0; i < alphabetLength; i++)
{
	charValues[i] = i + shiftBy;
}
var showCase = Math.pow((alphabetLength - 1 + shiftBy), e) % n;
encodingProcedure += '<br /><br />To encode a message, any instance of the character values of <b>' + charValues;
encodingProcedure += '</b> &ndash; derived from their alphabet of <b>' + alphabet + '</b> &ndash; must be raised to the';
encodingProcedure += ' power of <b>' + e + '</b> and then taken to their modulo in base <b>' + n + '</b>.';
encodingProcedure += ' For example, the value of the character <b>' + alphabet[alphabetLength - 1] + '</b>, which is <b>';
encodingProcedure += (alphabetLength - 1 + shiftBy) + '</b>, is raised to the ';
encodingProcedure += 'power of <b>' + e + '</b> modulo <b>' + n + '</b> which equals the value of the coded character <b>' + showCase + '</b>.';

// Write the encoding procedure...
document.getElementById("outputEncodingProcedure").innerHTML = '<i>Encoding Procedure:</i> <br />' + encodingProcedure;

var i = 0;
var secretCode = [];

for (i = 0; i < messageLength; i++)
{
	secretCode[i] = Math.pow(myAscii[i], e) % n;
}

// Write the coded message...
document.getElementById("outputCodedMessage").innerHTML = '<i>Coded Message:</i> <br /><span style="color: red;">' + secretCode + '</span>';

var showKase = Math.pow(secretCode[0], d) % n;
var decodingProcedure = 'To decode a coded message, their coded values must be raised to the';
decodingProcedure += ' power of <b>' + d + '</b> and then taken to their modulo in base <b>' + n + '</b>.';
decodingProcedure += ' For example, the value of the coded character <b>' + alphabet[alphabetLength - 1];
decodingProcedure += '</b>, which is <b>' + secretCode[0] + '</b>, is raised to the power of <b>';
decodingProcedure += d + '</b> modulo <b>' + n + '</b> which equals the myAsii value of <b>' + showKase + '</b>.';

// Write the encoding procedure...
document.getElementById("outputDecodingProcedure").innerHTML = '<i>Decoding Procedure:</i><br />' + decodingProcedure;

var decodedMyAscii = [];

for (i = 0; i < messageLength; i++)
{
	decodedMyAscii[i] = Math.pow(secretCode[i], d) % n;
}

// Write the decoded myAscii...
document.getElementById("outputDecodedMyAscii").innerHTML = '<i>Decoded back into myAscii Values:</i><br /><span style="color: orange;">' + decodedMyAscii + '</span>';

var decodedMessage = '';
var tempValue;

for (i = 0; i < messageLength; i++)
{
	tempValue = decodedMyAscii[i];
	decodedMessage += alphabet[tempValue - shiftBy];
}

// Write the decoded message...
document.getElementById("outputDecodedMessage").innerHTML = '<i>Decoded Message:</i> <br /><span style="color: blue;">' + decodedMessage + '</span>';

<div align="center">
<h1>
A Demonstration of RSA Math
</h1>

<h3 id="charSet"></h3>
<h3 id="inputText"></h3>
<h3 id="outputMyAscii"></h3>
<h3 id="outputCodedMessage"></h3>
<h3 id="outputDecodedMyAscii"></h3>
<h3 id="outputDecodedMessage"></h3>
</div>

<p id="outputEncodingProcedure"></p>

<br />

<p id="outputDecodingProcedure"></p>

<br />

<p>
Compare the procedures, above, with what the <a href="https://web.archive.org/web/20071101161340/https://www.rsa.com/rsalabs/node.asp?id=2214">RSA company says...</a>
</p>

<blockquote><hr>
The RSA algorithm works as follows: take two large primes, p and q, and compute their product n = pq; n is called the modulus. Choose a number, e, less than n and <i>relatively prime</i><b>[coprime]</b> to [<b>&phi;</b>](p-1)(q-1), which means e and [<b>&phi;</b>](p-1)(q-1) have no common factors except 1. Find another number d such that (ed - 1) is divisible by [<b>&phi;</b>](p-1)(q-1). <b>[e &times; d &equiv; 1 mod &phi;]</b> The values e and d are called the public and private exponents, respectively. The public key is the pair (n, e); the private key is (n, d). The factors p and q may be destroyed or kept with the private key.
<hr></blockquote>

<br />

<p>
Also, refer to: <a href="http://people.csail.mit.edu/rivest/Rsapaper.pdf">http://people.csail.mit.edu/rivest/Rsapaper.pdf</a>
</p>

<br />

<p>
Credit for learning how to do this goes to <a href="https://www.youtube.com/channel/UCCh8eOn7IubOKnw_TMS-25A">Jordan Haack</a> on YouTube: <a href="https://www.youtube.com/watch?v=e42kE9XIK7g"><i>RSA Encyption</i></a> (this is exactly how he spelled it). This exercise focuses on the math behind RSA encryption by limiting the alphabet's character set to a mere three to prevent JavaScript from causing errors.
</p>

<br />

<p>
Written by Vinyasi in the summer of 2016, copyleft.
</p>

<br /><br />

P {
  text-align: justify;
  text-indent: 50px;
  width: 50%;
  margin: auto;
  border: 3px none;
}
BLOCKQUOTE {
  text-align: justify;
  text-indent: 50px;
  width: 47%;
  margin: auto;
  border: 3px none;
}
A:active {text-decoration: none;}
A:hover {text-decoration: none; background-color: yellow;}