function fusker(uri) { // split up the uri into ranges and constants this.ranges = uri.match(/\[\d+-\d+\]/g); this.constants = uri.split(/\[\d+-\d+\]/g); // if there were no range matches, make this an empty // array to avoid problems if (!this.ranges) { this.ranges = new Array(); } // make the ranges suitable for use for (var i = 0; i < this.ranges.length; i++) { // split this range var split = this.ranges[i].match(/\d+/g); // turn the original into an object this.ranges[i] = { start: parseInt(split[0],10), end: parseInt(split[1],10), width: split[0].length }; // make sure the range is sane; if start < end, swap them // i may change this in the future to allow reverse iteration if (this.ranges[i].start > this.ranges[i].end) { var tmp = this.ranges[i].start; this.ranges[i].start = this.ranges[i].end; this.ranges[i].end = tmp; } } } fusker.prototype.limit = function() { // the limit will be at least 1 var limit = 1; // multiply by the size of each range for (var i = 0; i < this.ranges.length; i++) { limit *= this.ranges[i].end - this.ranges[i].start + 1; } // return the number of possible values return limit; } fusker.prototype.getURI = function(pos) { var i = this.constants.length - 1 var out = new String(); while (i >= 0) { out = this.constants[i] + out; i--; if (this.ranges[i] != undefined) { z = (this.ranges[i].start + pos % (this.ranges[i].end - this.ranges[i].start + 1)); var append = z.toString(); while (append.length < this.ranges[i].width) { append = '0' + append; } out = append + out; pos -= pos % (this.ranges[i].end - this.ranges[i].start + 1); pos /= (this.ranges[i].end - this.ranges[i].start + 1); } } return out; }