public static byte[] decrypt(byte[] data, byte[] key) {

        if(data.length == 0) {
            return data;
        }

        int[] s = Util.bytesToInts(data);
        int[] g = Util.bytesToInts(Arrays.copyOfRange(key, 0, 16));

        int d = s.length;
        int j = s[d - 1], l = s[0];
        int o = 0x9E3779B9;

        int m, i, a = (int) Math.floor(6 + 52 / d);
        int h = a * o;

        boolean printed = false;
        while(h != 0) {
            i = (h >>> 2 & 3);
            for(int c = d - 1; c >= 0; c--) {
                j = s[c > 0 ? c - 1 : d - 1];
                m = (j >>> 5 ^ l << 2) + (l >>> 3 ^ j << 4) ^ (h ^ l) + (g[(c & 3) ^ i] ^ j);
                if(!printed) {
                    printed = true;
                }
                l = s[c] -= m;
            }
            h -= o;
        }

        return Util.intsToBytes(s);
    }