Advertisement
aaaaaa123456789

JS ResizableMemoryBlock

Dec 2nd, 2016
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.    This code is hereby released to the public domain.
  3.    ~aaaaaa123456789, 2016-12-02, updated 2016-12-05
  4. */
  5.  
  6. function ResizableMemoryBlock (initial_size = 0) {
  7.   var self = this;
  8.  
  9.   var current_size;
  10.   var parts = [];
  11.  
  12.   for (current_size = 0; current_size < initial_size; current_size += 8192) parts[current_size >>> 13] = new DataView(new ArrayBuffer(8192));
  13.   current_size = initial_size;
  14.  
  15.   self.size = function () {
  16.     return current_size;
  17.   };
  18.  
  19.   function shrink (size) {
  20.     var new_parts = (size + 8191) >>> 13;
  21.     var old_offset = current_size & 8191, new_offset = size & 8191;
  22.     if (old_offset === 0) old_offset = 8192;
  23.     if (new_offset === 0) new_offset = 8192;
  24.     if (new_parts != parts.length) {
  25.       while (parts.length > new_parts) parts.pop();
  26.       old_offset = 8192;
  27.     }
  28.     var offset, part = parts.length - 1;
  29.     for (offset = new_offset; offset < old_offset; offset ++) parts[part].setUint8(offset, 0);
  30.     current_size = size;
  31.   }
  32.  
  33.   function expand (size) {
  34.     var new_parts = (size + 8191) >>> 13;
  35.     while (parts.length < new_parts) parts.push(new DataView(new ArrayBuffer(8192)));
  36.     current_size = size;
  37.   }
  38.  
  39.   self.resize = function (size) {
  40.     if (size == current_size) return;
  41.     if (size > current_size) return expand(size);
  42.     return shrink(size);
  43.   };
  44.  
  45.   function break_into_bytes (value, size) {
  46.     var bytes = [];
  47.     while (bytes.length < size) {
  48.       bytes.push(value & 0xff);
  49.       value >>>= 8;
  50.     }
  51.     return bytes;
  52.   }
  53.  
  54.   self.set_byte = function (position, value) {
  55.     if (position >= current_size) expand(position + 1);
  56.     parts[position >>> 13].setUint8(position & 8191, value & 0xff);
  57.   };
  58.  
  59.   self.set_halfword = function (position, value) {
  60.     if (position > (current_size - 2)) expand(position + 2);
  61.     var offset = position & 8191, part = position >>> 13;
  62.     value &= 0xffff;
  63.     if (offset <= 8190) return parts[part].setUint16(offset, value, true);
  64.     var bytes = break_into_bytes(value, 2);
  65.     while (bytes.length > 0) {
  66.       parts[part].setUint8(offset ++, bytes.shift());
  67.       if (offset == 8192) {
  68.         part ++;
  69.         offset = 0;
  70.       }
  71.     }
  72.   };
  73.  
  74.   self.set_word = function (position, value) {
  75.     if (position > (current_size - 4)) expand(position + 4);
  76.     var offset = position & 8191, part = position >>> 13;
  77.     value >>>= 0;
  78.     if (offset <= 8188) return parts[part].setUint32(offset, value, true);
  79.     var bytes = break_into_bytes(value, 4);
  80.     while (bytes.length > 0) {
  81.       parts[part].setUint8(offset ++, bytes.shift());
  82.       if (offset == 8192) {
  83.         part ++;
  84.         offset = 0;
  85.       }
  86.     }
  87.   };
  88.  
  89.   function gather_bytes (bytes) {
  90.     var result = 0;
  91.     while (bytes.length) result = ((result << 8) >>> 0) + bytes.pop();
  92.     return result;
  93.   }
  94.  
  95.   self.get_byte = function (position) {
  96.     if (position >= current_size) throw "attempted to read past the end of the buffer";
  97.     return parts[position >>> 13].getUint8(position & 8191);
  98.   };
  99.  
  100.   self.get_halfword = function (position) {
  101.     if (position > (current_size - 2)) throw "attempted to read past the end of the buffer";
  102.     var offset = position & 8191, part = position >>> 13;
  103.     if (offset <= 8190) return parts[part].getUint16(offset, true);
  104.     var bytes = [];
  105.     var count;
  106.     for (count = 0; count < 2; count ++) {
  107.       bytes.push(parts[part].getUint8(offset ++));
  108.       if (offset == 8192) {
  109.         offset = 0;
  110.         part ++;
  111.       }
  112.     }
  113.     return gather_bytes(bytes);
  114.   };
  115.  
  116.   self.get_word = function (position) {
  117.     if (position > (current_size - 4)) throw "attempted to read past the end of the buffer";
  118.     var offset = position & 8191, part = position >>> 13;
  119.     if (offset <= 8188) return parts[part].getUint32(offset, true);
  120.     var bytes = [];
  121.     var count;
  122.     for (count = 0; count < 4; count ++) {
  123.       bytes.push(parts[part].getUint8(offset ++));
  124.       if (offset == 8192) {
  125.         offset = 0;
  126.         part ++;
  127.       }
  128.     }
  129.     return gather_bytes(bytes);
  130.   };
  131.  
  132.   self.generate_array_buffer = function () {
  133.     var result = new ArrayBuffer(current_size);
  134.     var view = new Uint8Array(result);
  135.     var part_count = current_size >>> 13, extra_offset = current_size & 8191;
  136.     var pos;
  137.     for (pos = 0; pos < part_count; pos ++) view.set(new Uint8Array(parts[pos].buffer), (pos << 13) >>> 0);
  138.     for (pos = 0; pos < extra_offset; pos ++) view[pos + ((part_count << 13) >>> 0)] = parts[part_count].getUint8(pos);
  139.     return result;
  140.   };
  141.  
  142.   self.calculate_sha1 = function () {
  143.     function rotate (value, count) {
  144.       return ((value << count) | (value >>> (32 - count))) >>> 0;
  145.     }
  146.  
  147.     function mixing_function (counter, first, second, third) {
  148.       if (counter < 20)
  149.         return ((first & second) | (~first & third)) >>> 0;
  150.       else if ((counter >= 40) && (counter < 60))
  151.         return ((first & second) | (first & third) | (second & third)) >>> 0;
  152.       else
  153.         return (first ^ second ^ third) >>> 0;
  154.     }
  155.  
  156.     function hash_constant (counter) {
  157.       // 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)
  158.       return ([0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6])[(counter / 20) >>> 0];
  159.     }
  160.  
  161.     function process_block (state, block) {
  162.       var words = new Uint32Array(80);
  163.       var pos;
  164.       for (pos = 0; pos < 16; pos ++) words[pos] = block.getUint32(pos << 2);
  165.       for (; pos < 80; pos ++) words[pos] = rotate((words[pos - 3] ^ words[pos - 8] ^ words[pos - 14] ^ words[pos - 16]) >>> 0, 1);
  166.       var temp, a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
  167.       for (pos = 0; pos < 80; pos ++) {
  168.         temp = (rotate(a, 5) + mixing_function(pos, b, c, d) + e + words[pos] + hash_constant(pos)) >>> 0;
  169.         e = d;
  170.         d = c;
  171.         c = rotate(b, 30);
  172.         b = a;
  173.         a = temp;
  174.       }
  175.       return [(state[0] + a) >>> 0, (state[1] + b) >>> 0, (state[2] + c) >>> 0, (state[3] + d) >>> 0, (state[4] + e) >>> 0];
  176.     }
  177.  
  178.     var state = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
  179.     var pos, buf;
  180.     for (pos = 0; pos < ((current_size & 0xffffffc0) >>> 0); pos += 64)
  181.       state = process_block(state, new DataView(parts[pos >>> 13].buffer.slice(pos & 8191, (pos & 8191) + 64)));
  182.     buf = new DataView(new ArrayBuffer(64));
  183.     for (; pos < current_size; pos ++) buf.setUint8(pos & 63, parts[pos >>> 13].getUint8(pos & 8191));
  184.     buf.setUint8(pos & 63, 0x80);
  185.     if ((pos & 63) >= 56) {
  186.       state = process_block(state, buf);
  187.       buf = new DataView(new ArrayBuffer(64));
  188.     }
  189.     buf.setUint8(59, current_size >>> 29);
  190.     buf.setUint32(60, (current_size << 3) >>> 0);
  191.     state = process_block(state, buf);
  192.     buf = new Uint8Array(20);
  193.     for (pos = 0; pos < 20; pos ++) buf[pos] = (state[pos >> 2] >>> ((3 - (pos & 3)) << 3)) & 0xff;
  194.     return buf;
  195.   };
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement