JSFiddle - React, Tailwind, and code Playground
HTML
<div>Rule 30 Hash</div>
<input id="message" style="width:300px" onchange="calculateHash()" />
<button onclick="calculateHash()">Calculate</button>
<div><br /><code id="result"></code></div>
JavaScript
var RULE_30 = [0, 1, 1, 1, 1, 0, 0, 0];
var MAX_KEY = 80;
var MAX_HASH_BYTES = 32;
function getHash(message) {
var hash = new Uint8Array(MAX_HASH_BYTES);
var key = new Uint8Array(MAX_KEY);
var seed = 1;
var sum = 0;
for (var i = 0; i < message.length; i++) {
var c = message.charCodeAt(i) & 0xff;
seed = (seed * 1103515245 + 12345) % 0x80000000;
var r = Math.floor(seed / 65536) % 256;
var pos = i % MAX_KEY;
key[pos] = ((key[pos] ^ c) + sum + r) % 256;
sum += c;
}
key[i % MAX_KEY] ^= 1;
var skipRows = MAX_KEY * 32;
var maxCells = skipRows * 2;
maxCells += MAX_KEY * 8;
maxCells += MAX_HASH_BYTES * 8 * 4;
var cellsMid = maxCells / 2;
var cells = new Int8Array(maxCells);
var keyStart = (maxCells - MAX_KEY * 8) / 2;
for (var i = 0; i < key.length; i++) {
var keyChar = key[i];
var bitPos = 1;
for (var j = 0; j < 8; j++) {
var b = (keyChar & bitPos) >>> j;
cells[keyStart + i * 8 + j] = b;
bitPos <<= 1;
}
}
var bitCount = 0;
var mid = 0;
var maxRow = skipRows + MAX_HASH_BYTES * 8 * 2;
for (var row = 0; row < maxRow; row++) {
var tmp = 0;
for (var i = 0; i < cells.length - 2; i++) {
if (i == cellsMid) {
mid = cells[i];
}
var pattern = tmp * 4 + cells[i + 1] * 2 + cells[i + 2];
tmp = cells[i + 1];
var bit = RULE_30[pattern];
cells[i + 1] = bit;
}
if (row < skipRows) {
continue;
}
if (row % 2 == 1) {
if (mid == 1) {
var bufPos = bitCount >>> 3;
hash[bufPos] ^= 1 << (bitCount % 8);
}
bitCount++;
}
}
return hash;
}
function calculateHash() {
var input = document.getElementById('message');
var message = input.value;
var hash = getHash(message);
var hashString = '';
for (i = 0; i < hash.length; i++) {
var s = '0' + hash[i].toString(16);
hashString += s.length > 2 ? s.substring(1) : s;
}
var span =...