User:Martijn Hoekstra/ipv6range.js

(function{	Array.prototype.flatmap = function(f) {    	return Array.prototype.concat.apply([], this.map(f)); 	};    Array.prototype.zipWith = function(that, f) {      return this.map(function(v, i, a){ return f(v, that[i]); });   };	function rangeBase(address, size) {		var bitrange = parse_ip6(address);		var bitmask = makebitmask(128 - size);		var baserange = [bitrange[0] & bitmask[0], bitrange[1] & bitmask[1], bitrange[2] & bitmask[2], bitrange[3] & bitmask[3]];		return format_ip6(baserange);	}	function parse_ip6(addresstring) {		var hilo = addresstring.split("::");		var highblockstrings = hilo[0].split(":");		var lowblockstrings = hilo.length > 1 ? hilo[1].split(":") : [];		var highblocks = highblockstrings.map(function(str){return parseInt(str, 16);});		var lowblocks = lowblockstrings.map(function(str){return parseInt(str, 16);});		var result = [0,0,0,0];		highblocks.forEach(function(next, i, arr){ var ii = i >> 1; var add; if(i % 2 === 0){ add = next << 16; } else { add = next; }			result[ii] = (result[ii] | add); });		lowblocks.reverse.forEach(function(next, i, arr){ var add; if( i % 2 === 0) { add = next; } else { add = next << 16; }			var ri = 3 - (i >> 1); result[ri] = result[ri] | add; });		return result;	}	function format_ip6(range) {       console.debug("formatting", range);		var blocks = range.flatmap(int_2_blocks);        console.debug("blocks", blocks);		var msb = [];		var lsb = [];		var seenzero = false;		var skippingzero = false;		blocks.forEach(function(cur, i, arr){ if (skippingzero && cur === 0){ //skip } else { skippingzero = false; if(seenzero){ lsb.push(cur); } else { if(cur === 0){ seenzero = true; skippingzero = true; //skip } else { msb.push(cur); }				}				}		});		var msstring = msb.map(format_block).join(":");		var lsstring = lsb.map(format_block).join(":");		if (seenzero){			return msstring + "::" + lsstring;		} else {			return msstring;		}	}	function int_2_blocks(int){       if (int !== 0){ console.debug(int.toString(2));}		var result = [];		var lsmask = 0x0000ffff;		result[1] = int & lsmask;		result[0] = (int >>> 16);		return result;	}	//returns a hexstring of the four nibbles in the block	function format_block(block){		return block.toString(16);	}	function makebitmask(size) {      var maskblock = 3 - Math.floor(size/32);      var fullmask = [-1, -1, -1, -1];      var mymask = fullmask.map(function(v, i, arr){ if (i < maskblock){ return v;       } else if (i == maskblock){ var shift = size % 32; if (shift === 0) return -1; return v << shift; } else { return 0; }     });      return mymask;

}

});