# /* ================== */ # /* text_compressor.js */ # /* ================== */ function compress(string) { // Get the unique characters and numeric base. var unique = create_set(string); var base = unique.length; // Create a key that will encode data properly. shuffle(unique); var mapping = create_dict(unique); while (!mapping[string[string.length - 1]]) { shuffle(unique); mapping = create_dict(unique); } // Create a compressed numeric representation. var value = BigInteger(); for (var place = 0; place < string.length; place++) { var multiple = BigInteger(base).pow(place); var product = BigInteger(mapping[string[place]]).multiply(multiple); value = value.add(product); } // Return the number as a string with the table. return [array_to_string(decode(value)), unique.join("")]; } function create_set(string) { var set = new Object(); for (var index = 0; index < string.length; index++) { set[string[index]] = 0; } var array = new Array(); for (var value in set) { array.push(value); } return array; } function shuffle(array) { var range = array.length - 1; for (var index = 0; index < array.length; index++) { var destination = Math.floor(Math.random() * range); if (destination >= index) { destination++; } var temporary = array[destination]; array[destination] = array[index]; array[index] = temporary; } } function create_dict(array) { var dict = new Object(); for (var index = 0; index < array.length; index++) { dict[array[index]] = index; } return dict; } function decode(number) { // Change a number into a string. var array = new Array(); while (!number.isZero()) { var answer = number.divRem(256); number = answer[0]; array.push(answer[1]); } return array; } function array_to_string(array) { for (var index = 0; index < array.length; index++) { array[index] = String.fromCharCode(array[index]); } return array.join(""); } function decompress(string, key) { // Get the numeric value of the string. var number = encode(string); // Find the numeric base and prepare storage. var base = key.length; var array = new Array(); // Decode the value into the original string. while (!number.isZero()) { var answer = number.divRem(base); number = answer[0]; array.push(key[answer[1]]); } // Return the "string" as a bytes object. return array.join(""); } function encode(string) { // Change a string into a number. assert(string.length > 0 && string[string.length - 1] != String.fromCharCode(0), "String has ambiguous value!"); var value = BigInteger(); for (var shift = 0; shift < string.length; shift++) { var multiple = BigInteger(256).pow(shift); var product = BigInteger(string[shift].charCodeAt()).multiply(multiple); value = value.add(product); } return value; } function assert(okay, error) { if (!okay) { alert(error); throw new Error(error); } } # /* ======== */ # /* Test.htm */ # /* ======== */