Added new codebook page
This commit is contained in:
284
client/public/code-book-print.html
Normal file
284
client/public/code-book-print.html
Normal file
@@ -0,0 +1,284 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Code Book</title>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
@media print {
|
||||
@page {
|
||||
margin: 0.5in;
|
||||
}
|
||||
.page-break {
|
||||
page-break-before: always;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 10pt;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 14pt;
|
||||
margin-bottom: 0.5rem;
|
||||
border-bottom: 2px solid #000;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 12pt;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.key-section {
|
||||
margin-bottom: 1rem;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.key-value {
|
||||
font-weight: bold;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #000;
|
||||
padding: 0.15rem 0.25rem;
|
||||
text-align: center;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #ddd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ascii-table {
|
||||
width: 100%;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
.otp-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 0.5rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.otp-column {
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.otp-pair {
|
||||
margin: 0.1rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.auth-tables {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.auth-table-wrapper {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.auth-table-wrapper h3 {
|
||||
font-size: 10pt;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.auth-table-wrapper table {
|
||||
width: 100%;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
.pad-list {
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.pad-item {
|
||||
page-break-inside: avoid;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.pad-cipher {
|
||||
word-break: break-all;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Page 1: Key & ASCII -->
|
||||
<div>
|
||||
<div class="key-section">
|
||||
<h2>Encryption Key</h2>
|
||||
<div class="key-value" id="print-key"></div>
|
||||
</div>
|
||||
|
||||
<h2>ASCII Reference Table</h2>
|
||||
<div id="ascii-print"></div>
|
||||
</div>
|
||||
|
||||
<!-- Page 2+: OTP Pairs -->
|
||||
<div class="page-break">
|
||||
<h1>ONE-TIME PASSWORDS (HOTP)</h1>
|
||||
<div class="otp-grid" id="otp-grid"></div>
|
||||
</div>
|
||||
|
||||
<!-- Page 3+: Auth Tables -->
|
||||
<div class="page-break">
|
||||
<h1>AUTHENTICATION TABLES</h1>
|
||||
<div class="auth-tables" id="auth-tables"></div>
|
||||
</div>
|
||||
|
||||
<!-- Page 4+: Pad Keys -->
|
||||
<div class="page-break">
|
||||
<h1>ONE-TIME PAD</h1>
|
||||
<div class="pad-list" id="pad-list"></div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||
<script src="encryption.js"></script>
|
||||
<script>
|
||||
function getKey() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get('key') || localStorage.getItem('encryption_key') || '';
|
||||
}
|
||||
|
||||
function renderASCIITable() {
|
||||
let html = '<table class="ascii-table">';
|
||||
html += '<tr><th>Dec</th><th>Hex</th><th>Char</th><th>Dec</th><th>Hex</th><th>Char</th><th>Dec</th><th>Hex</th><th>Char</th><th>Dec</th><th>Hex</th><th>Char</th></tr>';
|
||||
|
||||
for (let row = 0; row < 32; row++) {
|
||||
html += '<tr>';
|
||||
for (let col = 0; col < 4; col++) {
|
||||
const code = row + (col * 32);
|
||||
if (code < 128) {
|
||||
const hex = code.toString(16).toUpperCase().padStart(2, '0');
|
||||
let char = String.fromCharCode(code);
|
||||
|
||||
if (code < 32) {
|
||||
const controlChars = ['NUL','SOH','STX','ETX','EOT','ENQ','ACK','BEL','BS','TAB','LF','VT','FF','CR','SO','SI',
|
||||
'DLE','DC1','DC2','DC3','DC4','NAK','SYN','ETB','CAN','EM','SUB','ESC','FS','GS','RS','US'];
|
||||
char = controlChars[code];
|
||||
} else if (code === 32) {
|
||||
char = 'SP';
|
||||
} else if (code === 127) {
|
||||
char = 'DEL';
|
||||
}
|
||||
|
||||
html += `<td>${code}</td><td>${hex}</td><td><b>${char}</b></td>`;
|
||||
}
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
|
||||
html += '</table>';
|
||||
document.getElementById('ascii-print').innerHTML = html;
|
||||
}
|
||||
|
||||
function renderOTPPairs(key) {
|
||||
const columns = [[], [], [], [], []];
|
||||
|
||||
for (let i = 0; i < 250; i++) {
|
||||
const nonce = i.toString().padStart(3, '0');
|
||||
const code = generateHOTP(key, nonce);
|
||||
const pair = `${nonce} ${code}`;
|
||||
columns[Math.floor(i / 50)].push(pair);
|
||||
}
|
||||
|
||||
let html = '';
|
||||
for (let col of columns) {
|
||||
html += '<div class="otp-column">';
|
||||
for (let pair of col) {
|
||||
html += `<div class="otp-pair">${pair}</div>`;
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
document.getElementById('otp-grid').innerHTML = html;
|
||||
}
|
||||
|
||||
function renderAuthTables(key) {
|
||||
let html = '';
|
||||
const rows = 'NOPQRSTUVWXYZ'.split('');
|
||||
const cols = 'ABCDEFGHIJKLM'.split('');
|
||||
|
||||
for (let tableIndex = 0; tableIndex < 26; tableIndex++) {
|
||||
const table = generateAuthTable(key, tableIndex);
|
||||
|
||||
html += '<div class="auth-table-wrapper">';
|
||||
html += `<h3>${PHONETIC[tableIndex]}</h3>`;
|
||||
html += '<table>';
|
||||
html += '<tr><th></th>';
|
||||
for (let col of cols) {
|
||||
html += `<th>${col}</th>`;
|
||||
}
|
||||
html += '</tr>';
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
html += `<tr><th>${rows[i]}</th>`;
|
||||
for (let j = 0; j < cols.length; j++) {
|
||||
html += `<td>${table[i][j]}</td>`;
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
document.getElementById('auth-tables').innerHTML = html;
|
||||
}
|
||||
|
||||
function renderPadKeys(key) {
|
||||
let html = '';
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const padKey = (i * 1000).toString().padStart(5, '0');
|
||||
const cipher = generatePadDisplay(key, padKey);
|
||||
|
||||
html += '<div class="pad-item">';
|
||||
html += `<div><b>Key: ${padKey}</b></div>`;
|
||||
html += `<div class="pad-cipher">${cipher}</div>`;
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
document.getElementById('pad-list').innerHTML = html;
|
||||
}
|
||||
|
||||
// Initialize
|
||||
const key = getKey();
|
||||
if (!key) {
|
||||
alert('No encryption key found! Redirecting to main page...');
|
||||
window.location.href = '/';
|
||||
} else {
|
||||
document.getElementById('print-key').textContent = key;
|
||||
renderASCIITable();
|
||||
renderOTPPairs(key);
|
||||
renderAuthTables(key);
|
||||
renderPadKeys(key);
|
||||
|
||||
// Auto-print after everything loads
|
||||
setTimeout(() => {
|
||||
window.print();
|
||||
}, 500);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user