package Encoder import BigString import BigNum import Execute import SeqWorker // Encodes numbers into ones with higher bases and represents them in the shortest possible way // Credits: Pipedream public constant maxInt = 2147483647 public constant maxHash = 1000 public class Encoder string charset int base real digits = 0. BigNum bignum construct(string charset) this.charset = charset this.base = charset.length() this.bignum = new BigNum(base) ondestroy destroy bignum function encode(int val, int max) digits = digits + log(max+1.,base+0.) bignum.mulSmall(max+1) bignum.addSmall(val) Log.trace("encoded val: " + val.toString() + " max: " + max.toString()) function decode(int max) returns int return bignum.divSmall(max+1) function isEmpty() returns boolean return bignum.isZero() function length() returns real return digits function clean() bignum.clean() function pad() BigNum_l cur = bignum.list BigNum_l prev = null int maxlen = R2I(1.0 + length()) while cur != null prev = cur cur = cur.next maxlen-- while maxlen > 0 prev.next = new BigNum_l() prev = prev.next maxlen-- function toString(BigString big, PayloadCallback onFinish) Log.debug("toString digits: " + digits.toString()) BigNum_l _cur = bignum.list doSeq() cb -> var continue = true if _cur != null big.addString(itochar(_cur.leaf)) _cur = _cur.next else continue = false onFinish.customData = big castTo int onFinish.doStep() return continue function fromString(BigString bs, PayloadCallback onFinishString) int _i = 0 var _cur = new BigNum_l() bignum.list = _cur Log.debug("from String") doSeq() cb -> var continue = true _cur.leaf = chartoi(bs.getString(_i, 1)) if _i < bs.getLength()-1 _cur.next = new BigNum_l() _cur = _cur.next _i++ else continue = false destroy bs onFinishString.doStep() return continue function hash() returns int Log.debug("hash") int hash = 0 int x BigNum_l cur = bignum.list while cur != null x = cur.leaf hash = ModuloInteger(hash+79*hash div (x+1) + 293*x div (1+hash - (hash div base)*base) + 479,maxHash) cur = cur.next Log.debug("hashed") return hash int hash = -1 function save(BigString bs, PayloadCallback onFinish) Log.debug("save1") execute(() -> clean()) Log.debug("save2") hash = -1 execute() -> hash = hash() nullTimer() -> Log.debug("hash: " + hash.toString()) execute(() -> encode(hash,maxHash)) Log.debug("encoded hash") execute(() -> clean()) Log.debug("clean") execute(() -> pad()) Log.debug("before toString bs: " + bs.getLength().toString()) execute(() -> toString(bs, onFinish)) var inputhash = -1 var comparehash = -1 function load(BigString bs, PayloadCallback onFinishLoad) inputhash = -1 comparehash = -1 fromString(bs) cb -> Log.debug("loaded..") execute() -> inputhash = decode(maxHash) Log.debug("decoded..") execute(() -> clean()) Log.debug("claned..") execute() -> comparehash = hash() Log.debug("hashed..") onFinishLoad.customData = (inputhash == comparehash).toInt() onFinishLoad.doStep() function chartoi( string c ) returns int int i = 0 let cs = charset let len = base while i < len and c != SubString(cs,i,i+1) i = i + 1 return i function itochar( int i ) returns string return SubString(charset,i,i+1)