taler-xotp

xOTP generator
Log | Files | Refs | Submodules | README

parserScript.js (7373B)


      1 /**
      2  *  Parsing module in JS using the baseX-Converter C library
      3  */
      4 
      5 let base32, base8, Module;
      6 const outSize = 128;
      7 
      8 const baseX_retValues = {
      9     1: "Argument Error",
     10     2: "Buffer Overflow",
     11     3: "Source Error",
     12     4: "Unexpected Error"
     13 }
     14 const placeholders = {
     15     base8_encode: "Enter text to base8 encoding",
     16     base8_decode: "Base-8 String (1-8)",
     17     base32_encode: "Enter text to base32 encoding",
     18     base32_decode: "Enter Base32-String"
     19 };
     20 
     21 const parserSelect = document.getElementById("baseX_parser");
     22 const inputField = document.getElementById("inputText");
     23 const outputField = document.getElementById("baseX-output");
     24 const copyButton = document.querySelector(".copy-button");
     25 
     26 // Load modules 
     27 Promise.all([
     28     Base32Module().then(mod => {
     29         base32 = {
     30             module: mod,
     31             encode: mod.cwrap('base32_encodeBytes', 'number', ['number', 'number', 'number', 'number']),
     32             decode: mod.cwrap('base32_decodeString', 'number', ['number', 'number', 'number', 'number', 'number']),
     33         }
     34     }),
     35 
     36     Base8Module().then(mod => {
     37         base8 = {
     38             module: mod,
     39             encode: mod.cwrap('base8_encodeBytes', 'number', ['number', 'number', 'number', 'number']),
     40             decode: mod.cwrap('base8_decodeNum', 'number', ['number', 'number', 'number', 'number', 'number']),
     41             stringToNum: mod.cwrap('base8_stringToNum', 'number', ['number', 'number'])
     42         };
     43     })
     44 ])
     45 
     46 function base8_encodeBytes(bytes) {
     47     const inputLength = bytes.length;
     48     const inputPtr = base8.module._malloc(inputLength);
     49     base8.module.HEAPU8.set(bytes, inputPtr);
     50     const outputPtr = base8.module._malloc(outSize); // 
     51     retVal = base8.encode(outputPtr, outSize, inputPtr, inputLength);
     52     if (0 != retVal) {
     53         throw new Error(`Encoding error with ${baseX_retValues[retVal]}`);
     54     }
     55     else {
     56         output = base8.module.UTF8ToString(outputPtr);
     57     }
     58     base8.module._free(inputPtr);
     59     base8.module._free(outputPtr);
     60     return output;
     61 }
     62 
     63 function base8_decodeString(input) {
     64     const inputLength = input.length;
     65     if (0 == inputLength) {
     66         return null;
     67     }
     68     const inputStrPtr = base8.module.allocateUTF8(input);
     69     const inputAsNumPtr = base8.module._malloc(inputLength);
     70     retVal = base8.stringToNum(inputAsNumPtr, inputStrPtr);
     71     if (retVal != 0) {
     72         throw new Error(`Parsing input to integer fails with: ${baseX_retValues[retVal]}`);
     73     }
     74     const outputPtr = base8.module._malloc(outSize);
     75     const outLengthPtr = base8.module._malloc(4); // 4 Bytes für int32
     76     retVal = base8.decode(outputPtr, outLengthPtr, outSize, inputAsNumPtr, inputLength);
     77 
     78     const outLength = base8.module.HEAP32[outLengthPtr >> 2];
     79 
     80     if (0 != retVal) {
     81         base8.module._free(inputAsNumPtr);
     82         base8.module._free(outputPtr);
     83         base8.module._free(outLengthPtr);
     84         base8.module._free(inputStrPtr);
     85         throw new Error(`Decoding error with: ${baseX_retValues[retVal]}`);
     86     }
     87     else {
     88         output = new Uint8Array(base8.module.HEAPU8.buffer, outputPtr, outLength);
     89     }
     90     base8.module._free(inputAsNumPtr);
     91     base8.module._free(outputPtr);
     92     base8.module._free(outLengthPtr);
     93     base8.module._free(inputStrPtr);
     94     return output;
     95 }
     96 
     97 
     98 function base32_encodeBytes(inputBytes) {
     99     const inputLength = inputBytes.length;
    100     const inputPtr = base32.module._malloc(inputLength);
    101     base32.module.HEAPU8.set(inputBytes, inputPtr);
    102     const outputPtr = base32.module._malloc(outSize); // 
    103     retVal = base32.encode(outputPtr, outSize, inputPtr, inputLength);
    104 
    105     output = base32.module.UTF8ToString(outputPtr);
    106     base32.module._free(inputPtr);
    107     base32.module._free(outputPtr);
    108     if (0 != retVal) {
    109         throw new Error(`Encoding error with ${baseX_retValues[retVal]}`);
    110     }
    111     else {
    112         return output;
    113     }
    114 }
    115 
    116 function base32_decodeString(inputString) {
    117     const inputLength = inputString.length;
    118     if (0 == inputLength) {
    119         return null;
    120     }
    121     const inputStrPtr = base32.module.allocateUTF8(inputString);
    122     const outputPtr = base32.module._malloc(outSize);
    123     const outLengthPtr = base32.module._malloc(4); // 4 Bytes für int32
    124     retVal = base32.decode(outputPtr, outLengthPtr, outSize, inputStrPtr);
    125     const outLength = base32.module.HEAP32[outLengthPtr >> 2];
    126     const decoded = new Uint8Array(base32.module.HEAPU8.buffer, outputPtr, outLength);
    127     // Free up memory
    128     base32.module._free(outLengthPtr);
    129     base32.module._free(inputStrPtr);
    130     base32.module._free(outputPtr);
    131     if (0 != retVal) {
    132         throw new Error(`Decoding base32 results in ${baseX_retValues[retVal]}`);
    133     }
    134     else {
    135         return decoded;
    136     }
    137 }
    138 
    139 function parseInput() {
    140     let output = "";
    141     let inputBytes;
    142 
    143     try {
    144         switch (baseX_parser.value) {
    145             case "base8_encode":
    146                 inputBytes = new TextEncoder().encode(inputField.value);
    147                 output = base8_encodeBytes(inputBytes);
    148                 break;
    149             case "base8_decode":
    150                 const decodedBase8 = base8_decodeString(inputField.value)
    151                 if (null != decodedBase8) {
    152                     const hexString = Array.from(decodedBase8)
    153                         .map(byte => byte.toString(16).padStart(2, '0')).join(', ');
    154                     const asciiString = new TextDecoder("utf-8").decode(decodedBase8);
    155                     output = hexString + '\n' + asciiString;
    156                 }
    157                 break;
    158             case "base32_encode":
    159                 inputBytes = new TextEncoder().encode(inputField.value);
    160                 output = base32_encodeBytes(inputBytes);
    161                 break;
    162             case "base32_decode":
    163                 const decodedBase32 = base32_decodeString(inputField.value);
    164                 if (null != decodedBase32) {
    165                     const hexString = Array.from(decodedBase32)
    166                         .map(byte => byte.toString(16).padStart(2, '0')).join(', ');
    167                     const asciiString = new TextDecoder("utf-8").decode(decodedBase32);
    168                     output = hexString + '\n' + asciiString;
    169                 }
    170                 break;
    171             case "base32_to_base8":
    172                 const base32Bytes = base32_decodeString(inputField.value);
    173                 if (null != base32Bytes) {
    174                     output = base8_encodeBytes(base32Bytes);
    175                 }
    176                 break;
    177             case "base8_to_base32":
    178                 const base8Bytes = base8_decodeString(inputField.value);
    179                 if (null != base8Bytes) {
    180                     output = base32_encodeBytes(base8Bytes);
    181                 }
    182                 break;
    183             default:
    184                 output = "Selection unknown";
    185         }
    186     } catch (e) {
    187         output = "Error at parsing: " + e.message;
    188     }
    189 
    190 
    191 
    192     if (output.trim() !== "") {
    193         copyButton.style.display = "block";
    194     } else {
    195         copyButton.style.display = "none";
    196     }
    197     outputField.textContent = output;
    198 }
    199 
    200 function updatePlaceholder() {
    201     const selected = parserSelect.value;
    202     inputField.placeholder = placeholders[selected] || "Input...";
    203 }
    204 
    205 parserSelect.addEventListener("change", () => {
    206     updatePlaceholder();
    207     parseInput();
    208 });
    209 
    210 document.getElementById("inputText").addEventListener("input", parseInput);
    211 
    212 // Set initial
    213 updatePlaceholder();