Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- This code is hereby released to the public domain.
- ~aaaaaa123456789, 2016-12-02, updated 2016-12-05
- */
- function ResizableMemoryBlock (initial_size = 0) {
- var self = this;
- var current_size;
- var parts = [];
- for (current_size = 0; current_size < initial_size; current_size += 8192) parts[current_size >>> 13] = new DataView(new ArrayBuffer(8192));
- current_size = initial_size;
- self.size = function () {
- return current_size;
- };
- function shrink (size) {
- var new_parts = (size + 8191) >>> 13;
- var old_offset = current_size & 8191, new_offset = size & 8191;
- if (old_offset === 0) old_offset = 8192;
- if (new_offset === 0) new_offset = 8192;
- if (new_parts != parts.length) {
- while (parts.length > new_parts) parts.pop();
- old_offset = 8192;
- }
- var offset, part = parts.length - 1;
- for (offset = new_offset; offset < old_offset; offset ++) parts[part].setUint8(offset, 0);
- current_size = size;
- }
- function expand (size) {
- var new_parts = (size + 8191) >>> 13;
- while (parts.length < new_parts) parts.push(new DataView(new ArrayBuffer(8192)));
- current_size = size;
- }
- self.resize = function (size) {
- if (size == current_size) return;
- if (size > current_size) return expand(size);
- return shrink(size);
- };
- function break_into_bytes (value, size) {
- var bytes = [];
- while (bytes.length < size) {
- bytes.push(value & 0xff);
- value >>>= 8;
- }
- return bytes;
- }
- self.set_byte = function (position, value) {
- if (position >= current_size) expand(position + 1);
- parts[position >>> 13].setUint8(position & 8191, value & 0xff);
- };
- self.set_halfword = function (position, value) {
- if (position > (current_size - 2)) expand(position + 2);
- var offset = position & 8191, part = position >>> 13;
- value &= 0xffff;
- if (offset <= 8190) return parts[part].setUint16(offset, value, true);
- var bytes = break_into_bytes(value, 2);
- while (bytes.length > 0) {
- parts[part].setUint8(offset ++, bytes.shift());
- if (offset == 8192) {
- part ++;
- offset = 0;
- }
- }
- };
- self.set_word = function (position, value) {
- if (position > (current_size - 4)) expand(position + 4);
- var offset = position & 8191, part = position >>> 13;
- value >>>= 0;
- if (offset <= 8188) return parts[part].setUint32(offset, value, true);
- var bytes = break_into_bytes(value, 4);
- while (bytes.length > 0) {
- parts[part].setUint8(offset ++, bytes.shift());
- if (offset == 8192) {
- part ++;
- offset = 0;
- }
- }
- };
- function gather_bytes (bytes) {
- var result = 0;
- while (bytes.length) result = ((result << 8) >>> 0) + bytes.pop();
- return result;
- }
- self.get_byte = function (position) {
- if (position >= current_size) throw "attempted to read past the end of the buffer";
- return parts[position >>> 13].getUint8(position & 8191);
- };
- self.get_halfword = function (position) {
- if (position > (current_size - 2)) throw "attempted to read past the end of the buffer";
- var offset = position & 8191, part = position >>> 13;
- if (offset <= 8190) return parts[part].getUint16(offset, true);
- var bytes = [];
- var count;
- for (count = 0; count < 2; count ++) {
- bytes.push(parts[part].getUint8(offset ++));
- if (offset == 8192) {
- offset = 0;
- part ++;
- }
- }
- return gather_bytes(bytes);
- };
- self.get_word = function (position) {
- if (position > (current_size - 4)) throw "attempted to read past the end of the buffer";
- var offset = position & 8191, part = position >>> 13;
- if (offset <= 8188) return parts[part].getUint32(offset, true);
- var bytes = [];
- var count;
- for (count = 0; count < 4; count ++) {
- bytes.push(parts[part].getUint8(offset ++));
- if (offset == 8192) {
- offset = 0;
- part ++;
- }
- }
- return gather_bytes(bytes);
- };
- self.generate_array_buffer = function () {
- var result = new ArrayBuffer(current_size);
- var view = new Uint8Array(result);
- var part_count = current_size >>> 13, extra_offset = current_size & 8191;
- var pos;
- for (pos = 0; pos < part_count; pos ++) view.set(new Uint8Array(parts[pos].buffer), (pos << 13) >>> 0);
- for (pos = 0; pos < extra_offset; pos ++) view[pos + ((part_count << 13) >>> 0)] = parts[part_count].getUint8(pos);
- return result;
- };
- self.calculate_sha1 = function () {
- function rotate (value, count) {
- return ((value << count) | (value >>> (32 - count))) >>> 0;
- }
- function mixing_function (counter, first, second, third) {
- if (counter < 20)
- return ((first & second) | (~first & third)) >>> 0;
- else if ((counter >= 40) && (counter < 60))
- return ((first & second) | (first & third) | (second & third)) >>> 0;
- else
- return (first ^ second ^ third) >>> 0;
- }
- function hash_constant (counter) {
- // constants used by SHA-1; they are actually simply the square roots of 2, 3, 5 and 10 as a fixed-point number (2.30 format)
- return ([0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6])[(counter / 20) >>> 0];
- }
- function process_block (state, block) {
- var words = new Uint32Array(80);
- var pos;
- for (pos = 0; pos < 16; pos ++) words[pos] = block.getUint32(pos << 2);
- for (; pos < 80; pos ++) words[pos] = rotate((words[pos - 3] ^ words[pos - 8] ^ words[pos - 14] ^ words[pos - 16]) >>> 0, 1);
- var temp, a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
- for (pos = 0; pos < 80; pos ++) {
- temp = (rotate(a, 5) + mixing_function(pos, b, c, d) + e + words[pos] + hash_constant(pos)) >>> 0;
- e = d;
- d = c;
- c = rotate(b, 30);
- b = a;
- a = temp;
- }
- return [(state[0] + a) >>> 0, (state[1] + b) >>> 0, (state[2] + c) >>> 0, (state[3] + d) >>> 0, (state[4] + e) >>> 0];
- }
- var state = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
- var pos, buf;
- for (pos = 0; pos < ((current_size & 0xffffffc0) >>> 0); pos += 64)
- state = process_block(state, new DataView(parts[pos >>> 13].buffer.slice(pos & 8191, (pos & 8191) + 64)));
- buf = new DataView(new ArrayBuffer(64));
- for (; pos < current_size; pos ++) buf.setUint8(pos & 63, parts[pos >>> 13].getUint8(pos & 8191));
- buf.setUint8(pos & 63, 0x80);
- if ((pos & 63) >= 56) {
- state = process_block(state, buf);
- buf = new DataView(new ArrayBuffer(64));
- }
- buf.setUint8(59, current_size >>> 29);
- buf.setUint32(60, (current_size << 3) >>> 0);
- state = process_block(state, buf);
- buf = new Uint8Array(20);
- for (pos = 0; pos < 20; pos ++) buf[pos] = (state[pos >> 2] >>> ((3 - (pos & 3)) << 3)) & 0xff;
- return buf;
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement