Search code examples
jsonbase64pako

json to base64 conversion


I have been looking at pako to change my base64 to JSON which I got to work perfectly. But how can I reverse it?

I have used an online JSON to base64 but the results are different from my original base64 that I originally input.

I have left a sample of my base64 within a comment on this snippet with its output (also commented). can I use pako to reverse it to its original state?

//eNqrVsoozcnxdFGyMjQwtjQwN9dRSq0oSC0qcSrNzElRskpLzClO1VEqT00syM8rVrKKNjUwMInVUSouSE3OBMpBRCxBItmZYAWGBgZmIINiawE68xw1
//{"hullID":1039077,"expertBuild":false,"weapons":[5004],"specials":[5009],"skins":[10069077]}   
    
submit.onclick = function(){
  // Get some base64 
  var b64Data     = document.getElementById("KixCode").value;;
  // Decode base64 (convert ascii to binary)
  var strData     = atob(b64Data);
  // Convert binary string to character-number array
  var charData    = strData.split('').map(function(x){return x.charCodeAt(0);});
  // Turn number array into byte-array
  var binData     = new Uint8Array(charData);
  // Pako magic
  var data        = pako.inflate(binData);
  // Convert gunzipped byteArray back to ascii string:
  var strData     = String.fromCharCode.apply(null, new Uint16Array(data));
  // Output 
  var KixCode = strData
  document.getElementById("output").innerText = KixCode;
}
<div>
<label for="KixCode">Kix Code: </label><input id="KixCode" type="text" value="eNqrVsoozcnxdFGyMjQwtjQwN9dRSq0oSC0qcSrNzElRskpLzClO1VEqT00syM8rVrKKNjUwMInVUSouSE3OBMpBRCxBItmZYAWGBgZmIINiawE68xw1"/><br /><br />
<button id="submit">Submit</button>
</div>
<p>
<span id="output"></span>
</p>

<script src="https://rawgit.com/nodeca/pako/master/dist/pako.js"></script>


Solution

  • You can use pako's deflate method. The problem is that the encoded data has some header information that gives information about how the compression was performed. This information is not included in the result of the decompression (inflate).

    Your example data turns out to have been compressed with level 7, but the default for the deflate method is level 6. This results in a difference in the second byte that is returned by deflate when compared to the second byte of the data that was passed to inflate. This second byte is part of the header.

    NB: I am not well versed in all this -- I just provide the above for your further analysis. The important thing is that options influence how the compression is performed.

    For your example, passing the option { level: 7 } to the deflate method will make the result like you passed it originally to inflate:

    submit.onclick = function(){
        var b64Data     = document.getElementById("KixCode").value;
        var strData     = atob(b64Data);
        var charData    = Array.from(strData, x => x.charCodeAt(0));
        var binData     = new Uint8Array(charData);
        var data        = pako.inflate(binData);
        var KixCode     = String.fromCharCode.apply(null, new Uint16Array(data));
        document.getElementById("output").innerText = KixCode;
        
        // Reverse operation
        var data2       = Array.from(KixCode, c => c.charCodeAt());
        var binData2    = pako.deflate(data2, { level: 7 }); // <-- option
        var charData2   = [...binData2];
        var strData2    = charData2.map(i => String.fromCharCode(i)).join("");
        var b64Data2    = btoa(strData2);
        
        document.getElementById("verif").innerText = b64Data2 === b64Data ? "Reversal is correct" : "Reversal is not the same";
    }
    <div><label for="KixCode">Kix Code: </label><input id="KixCode" type="text" style="width: 100%" value="eNqrVsoozcnxdFGyMjQwtjQwN9dRSq0oSC0qcSrNzElRskpLzClO1VEqT00syM8rVrKKNjUwMInVUSouSE3OBMpBRCxBItmZYAWGBgZmIINiawE68xw1"></div>
    <div><button id="submit">Submit</button></div>
    <div id="output"></div>
    <div id="verif"></div>
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.11/pako.min.js" integrity="sha512-euWc/Qv8Kp0CbTX1M+Q3BvUyoOaq9Au50TT7vz3MFf5ver39ybq6zV+RngDY8eN8AIQFigxjwYv6jhoP546vfQ==" crossorigin="anonymous"></script>