Line 1: | Line 1: | ||
− | + | <!DOCTYPE html> | |
<html> | <html> | ||
<head> | <head> | ||
Line 72: | Line 72: | ||
<hr class="clear" /> | <hr class="clear" /> | ||
<div id="sec-left"> | <div id="sec-left"> | ||
− | <p><div>Sub-coding: | + | <p><div><!--Sub-coding: |
<span> | <span> | ||
− | <input class="subcode" type="radio" id="code64" name="subcode" value="64" | + | <input class="subcode" type="radio" id="code64" name="subcode" value="64" /> |
<label for="code64">Six-four</label> | <label for="code64">Six-four</label> | ||
</span> | </span> | ||
<span> | <span> | ||
− | <input class="subcode" type="radio" id="code8" name="subcode" value="8bit" /> | + | <input class="subcode" type="radio" id="code8" name="subcode" value="8bit" checked /> |
<label for="code8">8-bit</label> | <label for="code8">8-bit</label> | ||
</span> | </span> | ||
Line 85: | Line 85: | ||
<label for="codex4">Ex-four</label> | <label for="codex4">Ex-four</label> | ||
</span> | </span> | ||
− | <span class="vr">​</span> | + | <span class="vr">​</span>--> |
<span> | <span> | ||
<input type="checkbox" id="crypt" /> | <input type="checkbox" id="crypt" /> | ||
Line 104: | Line 104: | ||
<p><div>Formatted</div><textarea rows="5" id="fmt"></textarea></p> | <p><div>Formatted</div><textarea rows="5" id="fmt"></textarea></p> | ||
<p><div>Encoded</div><div><textarea class="input" rows="5" id="enc"></textarea></div></p> | <p><div>Encoded</div><div><textarea class="input" rows="5" id="enc"></textarea></div></p> | ||
+ | <p><div>Total length: <span id="len"></span> bases</div></p> | ||
<p><div id="err"></div></p> | <p><div id="err"></div></p> | ||
</div> | </div> | ||
Line 113: | Line 114: | ||
The Key field is used for encryption & decryption and the | The Key field is used for encryption & decryption and the | ||
Formatted field shows more details about the message block.</p> | Formatted field shows more details about the message block.</p> | ||
− | <!--<span class="strike"><p>The encoding uses 6 bits, or 3 | + | <!--<span class="strike"><p>The encoding uses 6 bits, or 3 bases, per character, |
so the permitted characters are:</p> | so the permitted characters are:</p> | ||
<p><ul> | <p><ul> | ||
Line 122: | Line 123: | ||
<li>full-stop: <code>'.'</code>.</li> | <li>full-stop: <code>'.'</code>.</li> | ||
</ul></p></span>--> | </ul></p></span>--> | ||
− | <p>Different encodings for the message are possible. Both | + | <!--<p>Different encodings for the message are possible. Both |
− | 'Six-four' and 'Ex-four' use 6 bits (3 | + | 'Six-four' and 'Ex-four' use 6 bits (3 bases) per character, |
but are limited in the characters they allow. 'Six-four' allows | but are limited in the characters they allow. 'Six-four' allows | ||
only upper- and lower-case letters, digits, space and full-stop. | only upper- and lower-case letters, digits, space and full-stop. | ||
'Ex-four' is somewhat experimental and allows more characters | 'Ex-four' is somewhat experimental and allows more characters | ||
(all of ASCII and a few more), but needs 12 bits for some characters, | (all of ASCII and a few more), but needs 12 bits for some characters, | ||
− | most notably for upper-case.</p> | + | most notably for upper-case.</p>--> |
− | <p>' | + | <p>To counter restriction enzymes a sequence of 'A'-bases is |
− | character.</p> | + | inserted whereever the sequence for a restriction-enzyme occurs. |
+ | When decoding the message these sequences are removed. The length | ||
+ | of the substitution sequence is the shortest sequence of | ||
+ | 'A' that does not occur in the encoded message.</p> | ||
+ | <p>The encoding requires 4 bases per character.</p> | ||
<p>The fully encoded message block is formatted as follows:</p> | <p>The fully encoded message block is formatted as follows:</p> | ||
<p><ol> | <p><ol> | ||
− | <li>The letters <code>'Spy'</code> | + | <li>The letters <code>'Spy'</code>: 3 × 4 bases.</li> |
− | <li>The length of the encoded message: 16-bit number (8 | + | <li>Padding: 4 'A' bases.</li> |
− | <li>The checksum of the encoded message: 16-bit number (8 | + | <li>The length of the restriction-substitutes: 8-bit number (4 bases).</li> |
− | <li>The message: | + | <li>The length of the encoded message: 16-bit number (8 bases).</li> |
− | <li>The letters <code>'GEM'</code> | + | <li>The checksum of the encoded message: 16-bit number (8 bases).</li> |
+ | <li>The message: 4 bases per character.</li> | ||
+ | <li>The letters <code>'GEM'</code>: 3 × 4 bases.</li> | ||
</ol></p> | </ol></p> | ||
− | <p>The total overhead is | + | <p>The total overhead is 48 bases and the maximum message |
length is 65535 characters.</p> | length is 65535 characters.</p> | ||
− | <p>Encryption | + | <p>Encryption has an additional 8 characters (48 bases) overhead, |
− | + | regardless of key or message length.</p> | |
− | + | ||
</div> | </div> | ||
</div> | </div> | ||
Line 155: | Line 161: | ||
</div> | </div> | ||
− | <script src=" | + | <script src="crc.js"></script> |
− | <script src=" | + | <script src="dna.js"></script> |
− | <script src=" | + | <script src="eightbit.js"></script> |
− | <script src=" | + | <script src="sixfour.js"></script> |
− | <script src=" | + | <script src="restrict.js"></script> |
− | <script src=" | + | <script src="message.js"></script> |
− | <script src="/ | + | <script src="exfour.js"></script> |
− | <script src=" | + | <script src="aes.js"></script> |
− | <script src=" | + | <script src="aes-ctr.js"></script> |
+ | <script src="splitter.js"></script> | ||
<script> | <script> | ||
if(typeof Array.from !== 'function'){ | if(typeof Array.from !== 'function'){ | ||
Line 181: | Line 188: | ||
elDoDec = document.getElementById('doDec'), | elDoDec = document.getElementById('doDec'), | ||
elDirs = [elDoEnc, elDoDec], | elDirs = [elDoEnc, elDoDec], | ||
− | elSubs = Array.from(document.getElementsByClassName('subcode')); | + | elSubs = Array.from(document.getElementsByClassName('subcode')), |
+ | elLen = document.getElementById('len'); | ||
− | var subCoding = | + | var subCoding = EightBit, doCrypt = false, lastEdit = elMsg, cryptBits = 256; |
function showEncHdr(hdr, data){ | function showEncHdr(hdr, data){ | ||
elFmt.value = 'Start: Spy = '+hdr.dnaStart+', End: GEM = '+hdr.dnaEnd+ | elFmt.value = 'Start: Spy = '+hdr.dnaStart+', End: GEM = '+hdr.dnaEnd+ | ||
+ | '\nSubst: '+hdr.subst+' = '+hdr.dnaSubst+ | ||
'\nLength: '+hdr.len+' = '+hdr.dnaLen+ | '\nLength: '+hdr.len+' = '+hdr.dnaLen+ | ||
'\nCRC16: '+hdr.crc+' = '+hdr.dnaCrc+'\nData: '+data; | '\nCRC16: '+hdr.crc+' = '+hdr.dnaCrc+'\nData: '+data; | ||
Line 193: | Line 202: | ||
function showDecHdr(hdr){ | function showDecHdr(hdr){ | ||
elFmt.value = 'Start: '+hdr.dnaStart+' = Spy, End: '+hdr.dnaEnd+' = GEM'+ | elFmt.value = 'Start: '+hdr.dnaStart+' = Spy, End: '+hdr.dnaEnd+' = GEM'+ | ||
+ | '\nSubst: '+hdr.dnaSubst+' = '+hdr.subst+ | ||
'\nLength: '+hdr.dnaLen+' = '+hdr.len+ | '\nLength: '+hdr.dnaLen+' = '+hdr.len+ | ||
'\nCRC16: '+hdr.dnaCrc+' = '+hdr.crc+'\nData: '+hdr.data; | '\nCRC16: '+hdr.dnaCrc+' = '+hdr.crc+'\nData: '+hdr.data; | ||
Line 228: | Line 238: | ||
}catch(e){ | }catch(e){ | ||
elErr.innerHTML = e.message; | elErr.innerHTML = e.message; | ||
+ | console.error(e); | ||
return; | return; | ||
} | } | ||
Line 233: | Line 244: | ||
showEncHdr(hdr, data); | showEncHdr(hdr, data); | ||
elEnc.value = dna; | elEnc.value = dna; | ||
+ | elLen.innerHTML = dna.length; | ||
} | } | ||
Line 246: | Line 258: | ||
}catch(e){ | }catch(e){ | ||
elErr.innerHTML = e.message; | elErr.innerHTML = e.message; | ||
+ | console.error(e); | ||
return; | return; | ||
} | } | ||
Line 261: | Line 274: | ||
showDecHdr(hdr); | showDecHdr(hdr); | ||
elMsg.value = msg; | elMsg.value = msg; | ||
+ | elLen.innerHTML = dna.length; | ||
} | } | ||
Line 286: | Line 300: | ||
function updateCrypt(){ | function updateCrypt(){ | ||
− | if(this === elKey | + | if(this === elKey && this.value.length > 0){ |
elCrypt.checked = true; | elCrypt.checked = true; | ||
} | } | ||
Line 292: | Line 306: | ||
if(elCrypt.checked){ | if(elCrypt.checked){ | ||
doCrypt = true; | doCrypt = true; | ||
− | |||
subCoding = EightBit; | subCoding = EightBit; | ||
}else{ | }else{ |
Revision as of 13:12, 8 July 2016
<!DOCTYPE html>
SpyGEM coding & crypting
This page demonstrates the encoding and decoding of text messages into DNA, optionally with AES-256 encryption.
Enter a message into the Message field to have it encoded, or enter an encoded message into the Encoded field to have it decoded. The Key field is used for encryption & decryption and the Formatted field shows more details about the message block.
To counter restriction enzymes a sequence of 'A'-bases is inserted whereever the sequence for a restriction-enzyme occurs. When decoding the message these sequences are removed. The length of the substitution sequence is the shortest sequence of 'A' that does not occur in the encoded message.
The encoding requires 4 bases per character.
The fully encoded message block is formatted as follows:
- The letters
'Spy'
: 3 × 4 bases. - Padding: 4 'A' bases.
- The length of the restriction-substitutes: 8-bit number (4 bases).
- The length of the encoded message: 16-bit number (8 bases).
- The checksum of the encoded message: 16-bit number (8 bases).
- The message: 4 bases per character.
- The letters
'GEM'
: 3 × 4 bases.
The total overhead is 48 bases and the maximum message length is 65535 characters.
Encryption has an additional 8 characters (48 bases) overhead, regardless of key or message length.