UNPKG

@tgsnake/core

Version:

Pure Telegram MTProto library for nodejs

359 lines (358 loc) 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MAX_USER_ID = exports.MAX_USER_ID_OLD = exports.MIN_CHAT_ID = exports.MAX_CHANNEL_ID = exports.MIN_CHANNEL_ID = exports.bigMath = void 0; exports.bigintToBuffer = bigintToBuffer; exports.includesBuffer = includesBuffer; exports.sliceBuffer = sliceBuffer; exports.makeCRCTable = makeCRCTable; exports.crc32 = crc32; exports.sleep = sleep; exports.bufferToBigint = bufferToBigint; exports.mod = mod; exports.bigIntMod = bigIntMod; exports.range = range; exports.rangeBigint = rangeBigint; exports.randint = randint; exports.randBigint = randBigint; exports.pow = pow; exports.bigIntPow = bigIntPow; exports.getChannelId = getChannelId; exports.getPeerType = getPeerType; exports.base64urlTobase64 = base64urlTobase64; exports.generateRandomBigInt = generateRandomBigInt; exports.normalizeSecretString = normalizeSecretString; const platform_node_js_1 = require("./platform.node.js"); function bigintToBuffer(int, padding, litte = true, signed = false) { const bigintLength = int.toString(2).length; const bytes = Math.ceil(bigintLength / 8); if (padding < bytes) { throw new Error("Too big, Can't convert it to buffer with that padding."); } if (!signed && int < BigInt(0)) { throw new Error('Too small, can convert it when unsigned.'); } let isBellow = false; if (int < BigInt(0)) { isBellow = true; int = int * BigInt(-1); } const hex = int.toString(16).padStart(padding * 2, '0'); let buffer = platform_node_js_1.Buffer.from(hex, 'hex'); if (litte) buffer = buffer.reverse(); if (isBellow && signed) { if (litte) { let isReminder = false; if (buffer[0]) buffer[0] -= 1; for (let b = 0; b < platform_node_js_1.Buffer.byteLength(buffer); b++) { if (!buffer[b]) { isReminder = true; continue; } if (isReminder) { buffer[b] -= 1; isReminder = false; } buffer[b] = 255 - buffer[b]; } } else { buffer[platform_node_js_1.Buffer.byteLength(buffer) - 1] = 256 - buffer[platform_node_js_1.Buffer.byteLength(buffer) - 1]; for (let b = 0; b < platform_node_js_1.Buffer.byteLength(buffer); b++) { buffer[b] = 255 - buffer[b]; } } } return buffer; } function includesBuffer(array, buffer) { for (const buff of array) { if (buff.equals(buffer)) { return true; } } return false; } function sliceBuffer(buffer, start, stop, step = 1) { let slc = buffer.subarray(start, stop); let res = slc; if (step === 0) { throw new Error('slice step cannot be zero.'); } if (step < 0) { slc = platform_node_js_1.Buffer.from(buffer.subarray(stop - step, start - step)).reverse(); res = slc; step = -step; } if (step > 1) { res = platform_node_js_1.Buffer.alloc(0); let i = 0; for (const buff of slc) { i++; if (i >= step) { i = 0; } if (i === 1) { res = platform_node_js_1.Buffer.concat([ res, platform_node_js_1.Buffer.from([buff]), ]); } } } return res; } function makeCRCTable() { let c; const crcTable = []; for (let n = 0; n < 256; n++) { c = n; for (let k = 0; k < 8; k++) { c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; } crcTable[n] = c; } return crcTable; } function crc32(str) { str = platform_node_js_1.Buffer.isBuffer(str) ? platform_node_js_1.Buffer.from(str) : str; const crcTable = makeCRCTable(); const length = platform_node_js_1.Buffer.isBuffer(str) ? platform_node_js_1.Buffer.byteLength(str) : str.length; let crc = -1; for (let i = 0; i < length; i++) { const bytes = Number(str[i]); crc = (crc >>> 8) ^ crcTable[(crc ^ bytes) & 0xff]; } return (crc ^ -1) >>> 0; } function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } function bufferToBigint(buffer, little = true, signed = false) { const length = platform_node_js_1.Buffer.byteLength(buffer); const value = little ? buffer.reverse().toString('hex') : buffer.toString('hex'); const _bigint = (0, platform_node_js_1.bigInt)(value, 16); let bigint = BigInt(String(_bigint)); if (signed && Math.floor(bigint.toString(2).length / 8) >= length) { bigint = bigint - bigIntPow(BigInt(2), BigInt(length * 8)); } return BigInt(bigint); } function mod(n, m) { return ((n % m) + m) % m; } function bigIntMod(n, m) { return ((n % m) + m) % m; } function range(start, stop, step = 1) { const temp = []; const results = []; if (step === 0) { throw new Error('step cannot be zero'); } if (step < 0) { if (stop < 0) { for (let i = start; i > stop; i--) { temp.push(i); } step = -step; if (step > 1) { let i = 0; for (let num of temp) { i++; if (i >= step) { i = 0; } if (i === 1) { results.push(num); } } return results; } else { return temp; } } return results; } for (let i = start; i < stop; i++) { temp.push(i); } if (step > 1) { let i = 0; for (let num of temp) { i++; if (i >= step) { i = 0; } if (i === 1) { results.push(num); } } return results; } return temp; } function rangeBigint(start, stop, step = 1) { const temp = []; const results = []; if (step === 0) { throw new Error('step cannot be zero'); } if (step < 0) { if (stop < BigInt(0)) { for (let i = start; i > stop; i--) { temp.push(i); } step = -step; if (step > 1) { let i = 0; for (const num of temp) { i++; if (i >= step) { i = 0; } if (i === 1) { results.push(num); } } return results; } else { return temp; } } return results; } for (let i = start; i < stop; i++) { temp.push(i); } if (step > 1) { let i = 0; for (const num of temp) { i++; if (i >= step) { i = 0; } if (i === 1) { results.push(num); } } return results; } return temp; } function randint(min, max) { return Math.floor(Math.random() * (max - min)) + min; } function randBigint(min, max) { return platform_node_js_1.bigInt.randBetween(min, max).value; } function pow(x, y, z) { let result = Math.pow(x, y); if (z !== undefined) { return mod(result, z); } return result; } function bigIntPow(x, y, z) { if (z === undefined) { return x ** y; } else { let result = BigInt(1); while (y > BigInt(0)) { if (bigIntMod(y, BigInt(2)) === BigInt(1)) { result = bigIntMod(result * x, z); } y = y >> BigInt(1); x = bigIntMod(x * x, z); } return result; } } const bigMath = { abs(x) { return x < BigInt(0) ? -x : x; }, sign(x) { if (x === BigInt(0)) return BigInt(0); return x < BigInt(0) ? -BigInt(1) : BigInt(1); }, pow(base, exponent) { return base ** exponent; }, min(value, ...values) { for (const v of values) if (v < value) value = v; return value; }, max(value, ...values) { for (const v of values) if (v > value) value = v; return value; }, }; exports.bigMath = bigMath; exports.MIN_CHANNEL_ID = BigInt(-1002147483647); exports.MAX_CHANNEL_ID = BigInt(-1000000000000); exports.MIN_CHAT_ID = BigInt(-2147483647); exports.MAX_USER_ID_OLD = BigInt(2147483647); exports.MAX_USER_ID = BigInt(999999999999); function getChannelId(id) { return exports.MAX_CHANNEL_ID - id; } function getPeerType(id) { if (id < BigInt(0)) { if (exports.MIN_CHAT_ID <= id) return 'chat'; if (exports.MIN_CHANNEL_ID <= id < exports.MAX_CHANNEL_ID) return 'channel'; } else if (BigInt(0) < id <= exports.MAX_USER_ID) { return 'user'; } else { throw new Error(`PeerId Invalid: ${id}`); } } function base64urlTobase64(text) { const pad = text.length % 4; if (pad === 1) { throw new Error('Invalid base64url'); } return (pad === 2 || pad === 3 ? text.padEnd(4 - pad, '=') : text) .replace(/\-/g, '+') .replace(/_/g, '/'); } function generateRandomBigInt(lowBigInt, highBigInt) { if (lowBigInt >= highBigInt) { throw new Error('lowBigInt must be smaller than highBigInt'); } const difference = highBigInt - lowBigInt; const differenceLength = difference.toString().length; let multiplier = ''; while (multiplier.length < differenceLength) { multiplier += Math.random().toString().split('.')[1]; } multiplier = multiplier.slice(0, differenceLength); const divisor = '1' + '0'.repeat(differenceLength); const randomDifference = (difference * BigInt(multiplier)) / BigInt(divisor); return lowBigInt + randomDifference; } function normalizeSecretString(secret) { if (secret.slice(0, 2) === 'dd' || secret.slice(0, 2) === 'ee') { secret = secret.slice(2); } if (/^[0-9a-fA-F]+$/.test(secret)) { return platform_node_js_1.Buffer.from(secret, 'hex'); } return platform_node_js_1.Buffer.from(secret, 'base64').subarray(0, 16); }