export const MASK = 0xffffffff; export function zeroPad(arr, length) { return arr.concat((new Array(length)).fill(0)).slice(0, length); } export function bytes2int32(arr) { return arr.reduce((acc, b, i) => acc | b << (i*8)); } export function bytes2int32s(arr) { let res = []; for (let i = 0; i < arr.length; i += 4) { res.push(bytes2int32(arr.slice(i, i+4))); } return res; } /** * Converts a 32 bit integer into 4 bytes in little endian order. */ export function int322bytes(x) { let res = []; for (let i = 0; i < 4; i++) { res.push(x & 0xff); x >>>= 8; } return res; } /** * Converts a 32 bit integer into 4 bytes in big endian order. */ export function int322bytesBE(x) { let res = int322bytes(x); res.reverse(); return res; } export function int32s2bytes(arr) { return arr.map(int322bytes).reduce((acc, bytes) => acc.concat(bytes)); } export function bytes2hex(arr) { return arr.map(x => x.toString(16).padStart(2, "0")).join(""); } export function str2utf8(s) { let res = []; let c = s.codePointAt(0); for (let i=0; c!==undefined; i++, c=s.codePointAt(i)) { if (c < 0x80) {res.push(c);} else if (c < 0x800) { res.push(0b11000000 | (c >>> 6)); res.push(0b10000000 | (c & 0b111111)); } else if (c < 0x10000) { res.push(0b11100000 | (c >>> 12)); res.push(0b10000000 | ((c >>> 6) & 0b111111)); res.push(0b10000000 | (c & 0b111111)); } else { res.push(0b11110000 | (c >>> 18)); res.push(0b10000000 | ((c >>> 12) & 0b111111)); res.push(0b10000000 | ((c >>> 6) & 0b111111)); res.push(0b10000000 | (c & 0b111111)); } if (c > 0xffff) {i++;} // skip surrogate } return res; } export function utf82str(arr) { let res = []; for (let i = 0; i < arr.length; i++) { let x = arr[i]; if (x <= 0b1111111) {res.push(x);} else if (x <= 0b11011111) { let a = x & 0b11111; let b = arr[++i] & 0b111111; res.push(a << 6 | b); } else if (x <= 0b11101111) { let a = x & 0b1111; let b = arr[++i] & 0b111111; let c = arr[++i] & 0b111111; res.push(a << 12 | b << 6 | c); } else { let a = x & 0b111; let b = arr[++i] & 0b111111; let c = arr[++i] & 0b111111; let d = arr[++i] & 0b111111; res.push(a << 18 | b << 12 | c << 6 | d); } } return res.map(x => String.fromCodePoint(x)).join(""); } const mapping = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""); const remapping = new Array(128); mapping.forEach((c, i) => {remapping[c.charCodeAt(0)] = i;}); export function bytes2base64(byteArr) { let arr = byteArr.concat(); let out = []; let rem = (3 - arr.length%3) % 3; for (let i = 0; i < rem; i++) {arr.push(0);} // pad array to a multiple of 3 for (let i = 0; i < arr.length; i += 3) { // encode 3 bytes into 4 characters out.push(mapping[arr[i]>>>2 & 63]); out.push(mapping[((arr[i]&3) << 4) + (arr[i+1]>>>4 & 15)]); out.push(mapping[((arr[i+1]&15) << 2) + (arr[i+2]>>>6 & 3)]); out.push(mapping[arr[i+2] & 63]); } for (let i = 0; i < rem; i++) {out.pop();} for (let i = 0; i < rem; i++) {out.push("=");} return out.join(""); } export function base642bytes(str) { let out = []; for (let i = 0; i < str.length; i += 4) { let b1 = remapping[str.charCodeAt(i)]; let b2 = remapping[str.charCodeAt(i+1)]; let b3 = remapping[str.charCodeAt(i+2)]; let b4 = remapping[str.charCodeAt(i+3)]; out.push((b1<<2) + (b2>>4 & 3)); out.push(((b2&15) << 4) + (b3>>2 & 15)); out.push(((b3&3) << 6) + b4); } for (let i=1; i<3 && str[str.length-i]=="="; i++) {out.pop();} return out; } export function createRandomNonce(n) { let nonce = new Uint8Array(n); window.crypto.getRandomValues(nonce); return Array.from(nonce); }