UNPKG

@iabtechlabtcf/core

Version:

Ensures consistent encoding and decoding of TC Signals for the iab. Transparency and Consent Framework (TCF).

81 lines (80 loc) 3.12 kB
import { DecodingError, EncodingError } from '../errors/index.js'; export class Base64Url { /** * Base 64 URL character set. Different from standard Base64 char set * in that '+' and '/' are replaced with '-' and '_'. */ static DICT = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; static REVERSE_DICT = new Map([ ['A', 0], ['B', 1], ['C', 2], ['D', 3], ['E', 4], ['F', 5], ['G', 6], ['H', 7], ['I', 8], ['J', 9], ['K', 10], ['L', 11], ['M', 12], ['N', 13], ['O', 14], ['P', 15], ['Q', 16], ['R', 17], ['S', 18], ['T', 19], ['U', 20], ['V', 21], ['W', 22], ['X', 23], ['Y', 24], ['Z', 25], ['a', 26], ['b', 27], ['c', 28], ['d', 29], ['e', 30], ['f', 31], ['g', 32], ['h', 33], ['i', 34], ['j', 35], ['k', 36], ['l', 37], ['m', 38], ['n', 39], ['o', 40], ['p', 41], ['q', 42], ['r', 43], ['s', 44], ['t', 45], ['u', 46], ['v', 47], ['w', 48], ['x', 49], ['y', 50], ['z', 51], ['0', 52], ['1', 53], ['2', 54], ['3', 55], ['4', 56], ['5', 57], ['6', 58], ['7', 59], ['8', 60], ['9', 61], ['-', 62], ['_', 63], ]); /** * log2(64) = 6 */ static BASIS = 6; static LCM = 24; /** * encodes an arbitrary-length bitfield string into base64url * * @static * @param {string} str - arbitrary-length bitfield string to be encoded to base64url * @return {string} - base64url encoded result */ static encode(str) { /** * should only be 0 or 1 */ if (!/^[0-1]+$/.test(str)) { throw new EncodingError('Invalid bitField'); } /** * Pad the end of the string to the least common mutliple of 6 (basis for * base64) and 8 (one byte) */ const padding = str.length % this.LCM; str += padding ? '0'.repeat(this.LCM - padding) : ''; let result = ''; for (let i = 0; i < str.length; i += this.BASIS) { result += this.DICT[parseInt(str.substr(i, this.BASIS), 2)]; } return result; } /** * decodes a base64url encoded bitfield string * * @static * @param {string} str - base64url encoded bitfield string to be decoded * @return {string} - bitfield string */ static decode(str) { /** * should contain only characters from the base64url set */ if (!/^[A-Za-z0-9\-_]+$/.test(str)) { throw new DecodingError('Invalidly encoded Base64URL string'); } let result = ''; for (let i = 0; i < str.length; i++) { /** * index the binary value of the character from out reverse map */ const strBits = this.REVERSE_DICT.get(str[i]).toString(2); /** * Since a bit string converted to an integer on encoding will lose * leading zeros – pad to the left for those missing leading zeros */ result += '0'.repeat(this.BASIS - strBits.length) + strBits; } return result; } }