Skip to content

Instantly share code, notes, and snippets.

@zapthedingbat
Last active November 27, 2020 12:30
Show Gist options
  • Select an option

  • Save zapthedingbat/9a29c595d4ffa7ce41a0c68f45b21e10 to your computer and use it in GitHub Desktop.

Select an option

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
*/
Copy link
Copy Markdown

ghost 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