onetimepad implemented with vue
This commit is contained in:
parent
95e8eaa021
commit
6c30c8d4dc
2 changed files with 137 additions and 0 deletions
63
static/onetimepad/vue.html
Normal file
63
static/onetimepad/vue.html
Normal file
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>One Time Pad</title>
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1>One Time Pad</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Encrypt</h1>
|
||||
<form class="form-horizontal">
|
||||
<div id="encrypt" class="form-group">
|
||||
|
||||
<label for="encrypt-cleartext">Enter a message</label>
|
||||
<textarea id="encrypt-cleartext" class="form-control" v-model="cleartext"></textarea>
|
||||
|
||||
<label for="encrypt-binary">Message in binary</label>
|
||||
<textarea readonly id="encrypt-binary" class="form-control">{{ binary.cleartext }}</textarea>
|
||||
|
||||
<label for="encrypt-pad">One time pad</label>
|
||||
<textarea readonly id="encrypt-pad" class="form-control">{{ binary.pad }}</textarea>
|
||||
|
||||
<label for="encrypt-ciphertext">Ciphertext</label>
|
||||
<textarea readonly id="encrypt-ciphertext" class="form-control">{{ binary.ciphertext }}</textarea>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h1>Decrypt</h1>
|
||||
<form class="form-horizontal">
|
||||
<div id="decrypt" class="form-group">
|
||||
|
||||
<label for="decrypt-pad">Enter pad</label>
|
||||
<textarea id="decrypt-pad" class="form-control" v-model="pad"></textarea>
|
||||
|
||||
<label for="decrypt-ciphertext">Enter ciphertext</label>
|
||||
<textarea id="decrypt-ciphertext" class="form-control" v-model="ciphertext"></textarea>
|
||||
|
||||
<label for="decrypt-cleartext-binary">Cleartext (binary)</label>
|
||||
<textarea readonly id="decrypt-cleartext-binary" class="form-control">{{ cleartext.binary }}</textarea>
|
||||
|
||||
<label for="decrypt-message">Original Message</label>
|
||||
<textarea readonly id="decrypt-message" class="form-control">{{ cleartext.text }}</textarea>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="vue.js"></script>
|
||||
</body>
|
||||
</html>
|
74
static/onetimepad/vue.js
Normal file
74
static/onetimepad/vue.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
// http://stackoverflow.com/questions/10319415/unicode-to-binary
|
||||
var UTF_BITS = 8;
|
||||
|
||||
function padLeftTo(string, padChar, numChars) {
|
||||
return (new Array(numChars-string.length+1)).join(padChar) + string;
|
||||
}
|
||||
|
||||
function unicodeToBinary(char) {
|
||||
return char.split('').map(function(codepoint) {
|
||||
return padLeftTo(codepoint.charCodeAt(0).toString(2), 0, UTF_BITS);
|
||||
}).join('').split('').map(function(char){return parseInt(char)});
|
||||
// ^^^^( ignore this part if you just want a string )^^^^
|
||||
}
|
||||
|
||||
|
||||
function binaryToUnicode(binaryList) {
|
||||
var codepointsAsNumbers = [];
|
||||
while( binaryList.length>0 ){
|
||||
var codepointBits = binaryList.slice(0,UTF_BITS);
|
||||
binaryList = binaryList.slice(UTF_BITS);
|
||||
codepointsAsNumbers.push( parseInt(codepointBits.join(''),2) );
|
||||
}
|
||||
return String.fromCharCode.apply(this,codepointsAsNumbers);
|
||||
}
|
||||
|
||||
function newPad(len) {
|
||||
var arr = new Uint8Array(len)
|
||||
window.crypto.getRandomValues(arr)
|
||||
return arr.map(function(x) { return x % 2 })
|
||||
}
|
||||
|
||||
function xor(arr1, arr2) {
|
||||
return arr1.map(function(x, i) {
|
||||
var y = arr2[i];
|
||||
return x == y ? 0 : 1;
|
||||
})
|
||||
}
|
||||
|
||||
new Vue({
|
||||
el: "#encrypt",
|
||||
data: {
|
||||
cleartext: "Enter your message"
|
||||
},
|
||||
computed: {
|
||||
binary: function() {
|
||||
var cleartext = unicodeToBinary(this.cleartext),
|
||||
pad = newPad(cleartext.length),
|
||||
ciphertext = xor(cleartext, pad)
|
||||
return {
|
||||
cleartext: cleartext.join(""),
|
||||
pad: pad.join(""),
|
||||
ciphertext: ciphertext.join("")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
new Vue({
|
||||
el: "#decrypt",
|
||||
data: {
|
||||
pad: "1000101101100111111100101011001000101011011110010111111010111110010011000100100011100011",
|
||||
ciphertext: "1100001100000010100111101101111001000100010110010010100111010001001111100010010010000111"
|
||||
},
|
||||
computed: {
|
||||
cleartext: function() {
|
||||
var binary = xor(this.pad.split(""), this.ciphertext.split(""));
|
||||
return {
|
||||
binary: binary.join(""),
|
||||
text: binaryToUnicode(binary)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue