Line 1: | Line 1: | ||
{{Groningen}} | {{Groningen}} | ||
+ | <!DOCTYPE html> | ||
<html> | <html> | ||
<head> | <head> | ||
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> | <meta http-equiv="content-type" content="text/html; charset=utf-8" /> | ||
<title>SpyGEM coding</title> | <title>SpyGEM coding</title> | ||
− | <!-- <link rel="stylesheet" type="text/css" href=" | + | <!-- <link rel="stylesheet" type="text/css" href="reset.css" /> --> |
− | + | <style> | |
body{ | body{ | ||
font-family: sans-serif; | font-family: sans-serif; | ||
Line 66: | Line 67: | ||
clear: both; | clear: both; | ||
} | } | ||
− | </style | + | </style> |
</head> | </head> | ||
<body> | <body> | ||
− | <div | + | <div id="container"> |
<h1>SpyGEM coding & crypting</h1> | <h1>SpyGEM coding & crypting</h1> | ||
− | < | + | <hr class="clear" /> |
+ | <div id="sec-left"> | ||
<p><div> | <p><div> | ||
<span> | <span> | ||
Line 94: | Line 96: | ||
<p><div id="err"></div></p> | <p><div id="err"></div></p> | ||
</div> | </div> | ||
− | <div | + | <div id="sec-right"> |
<p>This page demonstrates the encoding and decoding of text messages | <p>This page demonstrates the encoding and decoding of text messages | ||
into DNA, optionally with AES-256 encryption.</p> | into DNA, optionally with AES-256 encryption.</p> | ||
Line 132: | Line 134: | ||
</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=" | + | <script src="splitter.js"></script> |
<script> | <script> | ||
if(typeof Array.from !== 'function'){ | if(typeof Array.from !== 'function'){ | ||
Line 159: | Line 161: | ||
elDoDec = document.getElementById('doDec'), | elDoDec = document.getElementById('doDec'), | ||
elDirs = [elDoEnc, elDoDec], | elDirs = [elDoEnc, elDoDec], | ||
− | |||
elLen = document.getElementById('len'); | elLen = document.getElementById('len'); | ||
Line 165: | Line 166: | ||
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+ | '\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;*/ |
+ | elFmt.value = "Total length: " + hdr.msg.length + | ||
+ | "\nMessage length: " + hdr.data.length; | ||
} | } | ||
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+ | '\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;*/ |
+ | elFmt.value = "Total length: " + hdr.msg.length + | ||
+ | "\nMessage length: " + hdr.data.length; | ||
} | } | ||
Line 216: | Line 221: | ||
elEnc.value = dna; | elEnc.value = dna; | ||
elLen.innerHTML = dna.length; | elLen.innerHTML = dna.length; | ||
+ | } | ||
+ | |||
+ | function decode(dna, err){ | ||
+ | if(dna.length < Message.minLength){ | ||
+ | throw err || new Error("Sequence too short to contain a message"); | ||
+ | } | ||
+ | |||
+ | var hdr = null; | ||
+ | try{ | ||
+ | hdr = Message.unpackDNA(dna, 1); | ||
+ | }catch(e){ | ||
+ | hdr = null; | ||
+ | if(!err || (e.level > err.level)){ | ||
+ | err = e; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if(hdr){ | ||
+ | return hdr; | ||
+ | } | ||
+ | |||
+ | var next = Message.findStart(dna, 1); | ||
+ | |||
+ | if(next === -1){ | ||
+ | throw err || new Error("No message head found"); | ||
+ | } | ||
+ | |||
+ | return decode(dna.substr(next), err); | ||
} | } | ||
Line 225: | Line 258: | ||
try{ | try{ | ||
− | hdr = Message.unpackDNA(dna, 1); | + | hdr = decode(dna, null); //Message.unpackDNA(dna, 1); |
msg = subCoding.decodeStr(hdr.data); | msg = subCoding.decodeStr(hdr.data); | ||
}catch(e){ | }catch(e){ | ||
Line 254: | Line 287: | ||
updateDec(); | updateDec(); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
function updateCrypt(){ | function updateCrypt(){ | ||
− | if(this === elKey | + | if(this === elKey && this.value.length > 0){ |
elCrypt.checked = true; | elCrypt.checked = true; | ||
} | } | ||
Line 305: | Line 324: | ||
elKey.onkeyup = updateCrypt.bind(elKey); | elKey.onkeyup = updateCrypt.bind(elKey); | ||
− | |||
− | |||
− | |||
elDirs.forEach(function(el){ | elDirs.forEach(function(el){ | ||
el.onchange = function(){ | el.onchange = function(){ | ||
Line 341: | Line 357: | ||
</body> | </body> | ||
</html> | </html> | ||
+ | {{Groningen/footer}} |
Revision as of 16:36, 25 August 2016
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.