Skip to content

Instantly share code, notes, and snippets.

@zapthedingbat
Last active November 27, 2020 12:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zapthedingbat/9a29c595d4ffa7ce41a0c68f45b21e10 to your computer and use it in GitHub Desktop.
Save zapthedingbat/9a29c595d4ffa7ce41a0c68f45b21e10 to your computer and use it in GitHub Desktop.
Compression and decompression for Google's appallingly inefficient additional consent string
/*
|| Compression and decompression using a combination of
|| Variable-length Quantity(VLQ) and Delta encoding to encode the "Additional
|| Consent" (AC) string required by Google’s Additional Consent Mode technical
|| specification https://support.google.com/admanager/answer/9681920?hl=en
||
|| vendorIds.compress(input)
|| input - A string of "." delimited list if ids in ascending order.
||
|| vendorIds.decompress(input)
|| input - The string created by a vendorIds.compress.
*/
var vendorIds = (function () {
var byChar = {};
var byOctet = {};
Array.prototype.slice
.call("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")
.forEach(function (a, c) {
(byChar[a] = c), (byOctet[c] = a);
});
return {
compress: function (input) {
var ids = [];
var prev = 0;
return (
input
.split(".")
.map(function (a) {
var b = parseInt(a, 10);
var c = b - prev;
prev = b;
return c;
})
.forEach(function (a) {
do {
var b = 31 & a;
a >>>= 5;
if (0 < a) {
b |= 32;
}
ids.push(b);
} while (0 < a);
}),
ids
.map(function (a) {
return byOctet[a];
})
.join("")
);
},
decompress: function (input) {
var octets = Array.prototype.slice.call(input).map(function (a) {
return byChar[a];
});
var ids = [],
shift = 0,
b = 0,
prev = 0;
for (var a, j = 0; j < octets.length; j += 1) {
a = octets[j];
var flag = a & 32;
a &= 31;
b += a << shift;
if (flag) {
shift += 5;
} else {
// Delta decoding
var h = prev + b;
prev = h;
ids.push(h);
b = shift = 0;
}
}
return ids.join(".");
},
};
})();
/*
|| Example usage
*/
var testInput =
"39.43.46.55.61.66.70.83.89.93.108.117.122.124.131.135.136.143.144.147.149.159.162.167.171.184.192.196.202.211.218.228.230.239.241.253.259.266.272.286.291.311.317.322.323.326.327.338.367.371.385.389.393.394.397.407.413.415.424.430.436.440.445.448.449.453.482.486.491.494.495.501.503.505.522.523.540.550.559.560.568.571.574.576.584.585.587.588.591.733.737.745.780.787.802.803.817.820.821.829.839.853.864.867.874.899.904.922.931.938.979.981.985.1003.1024.1027.1031.1033.1034.1040.1046.1051.1053.1067.1085.1092.1095.1097.1099.1107.1126.1127.1135.1143.1149.1152.1162.1166.1171.1186.1188.1192.1201.1204.1205.1211.1215.1226.1227.1230.1248.1252.1268.1270.1276.1284.1286.1290.1301.1307.1312.1317.1329.1345.1356.1364.1365.1375.1403.1411.1415.1416.1419.1440.1442.1449.1455.1456.1465.1495.1512.1516.1525.1540.1548.1555.1558.1564.1570.1577.1579.1583.1584.1591.1603.1613.1616.1638.1651.1653.1665.1667.1671.1677.1678.1682.1697.1699.1703.1712.1716.1721.1722.1725.1732.1745.1750.1753.1765.1769.1782.1786.1800.1808.1810.1825.1827.1832.1837.1838.1840.1842.1843.1844.1845.1859.1866.1870.1878.1880.1889.1898.1899.1917.1929.1942.1944.1962.1963.1964.1967.1968.1969.1978.1998.2003.2007.2013.2027.2035.2039.2044.2047.2052.2056.2064.2068.2070.2072.2074.2088.2090.2103.2107.2109.2115.2124.2130.2133.2137.2140.2145.2147.2150.2156.2166.2177.2179.2183.2186.2202.2205.2213.2216.2219.2220.2222.2225.2234.2253.2264.2279.2282.2292.2299.2305.2309.2312.2316.2325.2328.2331.2334.2335.2336.2337.2343.2354.2357.2358.2359.2366.2370.2373.2376.2377.2387.2392.2394.2400.2403.2405.2406.2407.2411.2414.2416.2418.2425.2427.2440.2447.2459.2461.2462.2468.2472.2477.2481.2484.2486.2488.2492.2493.2496.2497.2498.2499.2504.2510.2511.2517.2526.2527.2531.2532.2534.2535.2542.2544.2552.2555.2563.2564.2567.2568.2569.2571.2572.2575.2577.2583.2584.2589.2595.2596.2601.2604.2605.2608.2609.2610.2612.2614.2621.2628.2629.2633.2634.2636.2642.2643.2645.2646.2647.2650.2651.2652.2656.2657.2658.2660.2661.2669.2670.2673.2677.2681.2682.2684.2686.2687.2690.2691.2695.2698.2707.2713.2714.2729.2739.2767.2768.2770.2771.2772.2784.2787.2791.2792.2797.2798.2801.2805.2812.2813.2816.2817.2818.2821.2822.2827.2830.2831.2834.2836.2838.2839.2840.2844.2846.2847.2849.2850.2851.2852.2854.2856.2860.2862.2863.2865.2867.2869.2873.2874.2875.2876.2878.2879.2880.2881.2882.2883.2884.2885.2886.2887.2888.2889.2891.2893.2894.2895.2897.2898.2900.2901.2908.2909.2911.2912.2913.2914.2916.2917.2918.2919.2920.2922.2923.2924.2927.2929.2930.2931.2933.2939.2940.2941.2942.2947.2949.2950.2956.2961.2962.2963.2964.2965.2966.2968.2969.2970.2973.2974.2975.2979.2980.2981.2983.2985.2986.2987.2991.2993.2994.2995.2997.3000.3002.3003.3005.3008.3009.3010.3011.3012.3016.3017.3018.3019.3024.3025.3033.3034.3037.3038.3043.3044.3045.3048.3050.3051.3052.3053.3055.3058.3059.3063.3065.3066.3068.3070.3072.3073.3074.3075.3076.3077.3078.3089.3090.3093.3094.3095.3097.3099.3100.3104.3106.3108.3109.3111.3112.3116.3117.3118.3119.3120.3121.3124.3126.3127.3128.3130.3135.3136.3139.3145.3149.3150.3151.3154.3155.3159.3162.3163.3165.3167.3172.3173.3180.3184.3185.3187.3188.3189.3190.3194.3196.3197";
var testCompressed = vendorIds.compress(testInput);
var testResult = vendorIds.decompress(testCompressed);
console.log("Round Trip OK", testResult == testInput);
console.log("Input size", testInput.length);
console.log("Compressed size", testCompressed.length);
/*
|| Expected Output
*/
/*
Round Trip OK true
Input size 3086
Compressed size 646
*/
@fatmambo33
Copy link

fatmambo33 commented Nov 27, 2020

thanks to the bat!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment