简体   繁体   中英

Trouble decoding tiled base64 data with javascript

I'm using tiled to create a tile map. (Tiled is a tile map editor with support for orthogonal and isometric maps)

It saves the map in an XML file. It can use certain encoding structures:

  • regular base64
  • base64 + gzip
  • base64 + zlib
  • regular csv

Now, I've completely given up on gzip (my server gzips traffic it anyway, so no loss there) So I thought I'd try regular base64 decoding, using a base64 jquery plugin

But the data comes out all garbled, like this:

��������������������������������������������������������

I guess it's binary encoding it, but how do I get around that?

Example data that needs to be decoded (regular base64):

jQAAAI4AAACPAAAAkAAAAJEAAACSAAAAkwAAAKEAAACiAAAAowAAAKQAAAClAAAApgAAAKcAAAA=

Example data that needs to be decoded (gzipped base64):

H4sIAAAAAAAACw3DhwnAMAwAMP8P2Rdk9s1KoBQR2WK12R1Ol9vj9fn5A/luZ4Y4AAAA

Example data as csv:

141,142,143,144,145,146,147,
161,162,163,164,165,166,167

So how can I turn the regular base64 encoded bit and turn it into the csv?

Edit:

Using the solution Pointy found I got a semi-correct array. After a few thousand characters the 2 numbers would be wrong again, though. And even more frequent after that.

I then found someone who also uses tiled and the base64 encoding in his scheme. After he decoded the array, he also did this to it:

        var d = base64_decode($(this).find('data').text());
    var e = new Array();
    for (var i = 0; i <= d.length; i += 4) {
    var f = d[i] | d[i + 1] << 8 | d[i + 2] << 16 | d[i + 3] << 24;
    e.push(f)
    }

I have no idea why this is needed, but at least it works. If anyone could explain, please do!

Try looking at the returned string character by character. In other words, get the "charCodeAt" for each character in the array.

function codesFromString(str) {
  var rv = [];
  for (var i = 0; i < str.length; ++i)
    rv.push(str.charCodeAt(i));
  }
  return rv;
}

That leaves you with an array of numbers. If you want to dump that out as CSV on a page or something, you can use join()

var csv = codeFromString(decoded).join(',');

edit — ok here's a base64 numeric decoder:

  var base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split("");
  var base64inv = {}; 
  for (var i = 0; i < base64chars.length; i++) { 
    base64inv[base64chars[i]] = i; 
  }
  function decodeNumeric(s) {
    s = s.replace(new RegExp('[^'+base64chars.join("")+'=]', 'g'), "");

    var p = (s.charAt(s.length-1) == '=' ? 
            (s.charAt(s.length-2) == '=' ? 'AA' : 'A') : ""); 
    var r = []; 
    s = s.substr(0, s.length - p.length) + p;

    for (var c = 0; c < s.length; c += 4) {
      var n = (base64inv[s.charAt(c)] << 18) + (base64inv[s.charAt(c+1)] << 12) +
              (base64inv[s.charAt(c+2)] << 6) + base64inv[s.charAt(c+3)];

      r.push((n >>> 16) & 255);
      r.push((n >>> 8) & 255);
      r.push(n & 255);
    }
    return r;
  }

That works on your sample, but it demonstrates that what you've written as the result is not actually correct. Instead of "141,142,143,..." it's "141,0,0,0,142,0,0,0,143,0,0,0" etc. That's what those runs of "AAA" in the encoded string are.

(code stolen from http://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64 )

老话题,我知道,但你最后一个问题的答案在这里: http//sourceforge.net/apps/mediawiki/tiled/index.php?title = Examining_the_map_format

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM