function generateRandomCharacters(length) {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' +
        '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';  // All printable characters
    let result = '';

    for (let i = 0; i < length; i++) {
        const randomIndex = Math.floor(Math.random() * characters.length);
        result += characters[randomIndex];
    }

    return result;
}

export function encode(input, paddedInputLength=256) {
    const paddedInput = input + generateRandomCharacters(paddedInputLength - input.length);
    const encoded = btoa(paddedInput);

    const mask = generateRandomCharacters(paddedInputLength);

    // Take the XOR of encoded and mask
    let maskedEncoded = '';
    for (let i = 0; i < encoded.length; i++) {
        const charCodeEncoded = encoded.charCodeAt(i);
        const charCodeMask = mask.charCodeAt(i);
        const maskedCharCode = charCodeEncoded ^ charCodeMask;
        maskedEncoded += String.fromCharCode(maskedCharCode);
    }

    const maskEncoded = btoa(mask);
    const finalEncoded = btoa(maskedEncoded);

    return [finalEncoded, maskEncoded];
}

export function decode(finalEncoded, maskEncoded, length) {
    const mask = atob(maskEncoded);
    const maskedEncoded = atob(finalEncoded);

    let encoded = '';
    for (let i = 0; i < maskedEncoded.length; i++) {
        const charCodeMasked = maskedEncoded.charCodeAt(i);
        const charCodeMask = mask.charCodeAt(i);
        const originalCharCode = charCodeMasked ^ charCodeMask;
        encoded += String.fromCharCode(originalCharCode);
    }

    const paddedInput = atob(encoded);
    return paddedInput.slice(0, length);
}
